/ UIKit / Android View
UIKit
Chat UIKit Android View v3
Chat UIKit Android View
Chat UIKit
Android View
Version 3

Customize module layout

Copy link

This guide provides insights on how to effectively utilize and modify the Module UI for advanced customizations.


Add a new view to the module

Copy link

You have the flexibility to add a new view to the existing chat UI. For example, a UI element like the FloatingActionButton is designed to overlay on top of other views. This means they are not constrained by the boundaries of existing components in the module. The following code shows how you can add such views to the module.

Example

Copy link

Define the new UI view in XML. The following demonstrates how to overlay a FloatingActionButton on the existing Channel screen.

First, define your new UI element in the XML layout. Below is an example showing how to overlay a FloatingActionButton on the existing Channel screen. In this XML layout, the channelView FrameLayout serves as the placeholder for the Channel screen.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <FrameLayout
        android:id="@+id/channelView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="@dimen/sb_size_64"
        android:layout_height="@dimen/sb_size_64"
        app:fabCustomSize="@dimen/sb_size_64"
        android:src="@drawable/icon_plus"
        android:layout_gravity="end|bottom"
        android:layout_marginBottom="@dimen/sb_size_64"
        android:layout_marginEnd="@dimen/sb_size_16"
        />

</FrameLayout>

With the XML layout defined, the next step involves adjusting the view within onCreateView. First, inflate the UI constructed in view_channel_layout_sample.xml. Next, create the default Channel view using super.onCreateView(). Then, add it to the channelView FrameLayout defined in the xml above. The implementation is shown in the code below.

class ChannelLayoutSampleModule(context: Context) : ChannelModule(context) {
    override fun onCreateView(context: Context, inflater: LayoutInflater, args: Bundle?): View {
        val binding = ViewChannelLayoutSampleBinding.inflate(inflater)
        val channelView = super.onCreateView(context, inflater, args)
        binding.channelView.addView(channelView)
        binding.fab.setOnClickListener {
            Toast.makeText(context, "Floating Button Clicked", Toast.LENGTH_SHORT).show()
        }
        return binding.root
    }
}

Modify position of existing module components

Copy link

You can rearrange the components of a module for a customized user experience. You retrieve the components from a module and call the component's onCreateView.

Note that for the default UI to operate correctly, you need to extract and apply the existing UIKit Theme when customizing.

override fun onCreateView(context: Context, inflater: LayoutInflater, args: Bundle?): View {
    val moduleContext: Context = ContextThemeWrapper(context, params.theme)
    val parent = LinearLayout(context)
    parent.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
    parent.orientation = LinearLayout.VERTICAL

    val values = TypedValue()
    if (params.shouldUseHeader()) {
        moduleContext.theme.resolveAttribute(R.attr.sb_component_header, values, true)
        val headerThemeContext: Context = ContextThemeWrapper(moduleContext, values.resourceId)
        val headerInflater = inflater.cloneInContext(headerThemeContext)
        val header = headerComponent.onCreateView(headerThemeContext, headerInflater, parent, args)
        parent.addView(header)
    }

    val bodyContainer = FrameLayout(context)
    bodyContainer.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1.0f)
    parent.addView(bodyContainer)

    moduleContext.theme.resolveAttribute(R.attr.sb_component_list, values, true)
    val listThemeContext: Context = ContextThemeWrapper(moduleContext, values.resourceId)
    val listInflater = inflater.cloneInContext(listThemeContext)
    val messageListLayout = messageListComponent.onCreateView(listThemeContext, listInflater, bodyContainer, args)
    bodyContainer.addView(messageListLayout)

    moduleContext.theme.resolveAttribute(R.attr.sb_component_status, values, true)
    val statusThemeContext: Context = ContextThemeWrapper(moduleContext, values.resourceId)
    val statusInflater = inflater.cloneInContext(statusThemeContext)
    val statusLayout = statusComponent.onCreateView(statusThemeContext, statusInflater, bodyContainer, args)
    bodyContainer.addView(statusLayout)

    moduleContext.theme.resolveAttribute(R.attr.sb_component_channel_message_input, values, true)
    val inputThemeContext: Context = ContextThemeWrapper(moduleContext, values.resourceId)
    val inputInflater = inflater.cloneInContext(inputThemeContext)
    val inputLayout = messageInputComponent.onCreateView(inputThemeContext, inputInflater, parent, args)
    parent.addView(inputLayout)
}

For an in-depth practical demonstration, see our sample code.