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

Customize selection for users

Copy link

By default, Sendbird UIKit for Android supports multi-selection in the user list. This section guides you on how to customize the number of selections available.


Available selection screens

Copy link

The following table shows a list of all fragments and its adapters that support user selection.

FragmentAdapter

CreateChannelFragment

CreateChannelUserListAdapter

InviteUserFragment

InviteUserListAdapter

RegisterOperatorFragment

RegisterOperatorListAdapter

OpenChannelRegisterOperatorFragment

OpenChannelRegisterOperatorListAdapter


Limit the number of selection

Copy link

To customize the selection, you need to override the interaction within the ViewHolder where the selectedUserIdList is modified through adding or removing. This requires creating a custom ViewHolder and Adapter classes. For additional information, refer to the applying custom adapters page.

The following example is an implementation of a CreateChannelUserListAdapter that limits the number of selectable users.

class CustomSelectionCreateChannelUserListAdapter(private val maxSelectionCount: Int) : CreateChannelUserListAdapter() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<UserInfo> {
        return SelectUserViewHolder(ViewSelectUserBinding.inflate(LayoutInflater.from(parent.context), parent, false))
    }

    override fun onBindViewHolder(holder: BaseViewHolder<UserInfo>, position: Int) {
        val userInfo = getItem(position)
        holder.bind(userInfo)
    }

    inner class SelectUserViewHolder(internal val binding: ViewSelectUserBinding) : BaseViewHolder<UserInfo>(binding.root) {
        init {
            binding.root.setOnClickListener { v ->
                val userPosition = bindingAdapterPosition
                if (userPosition != RecyclerView.NO_POSITION) {
                    if (onCheckChanged(userPosition)) {
                        binding.cbUserPreview.toggle()
                    }
                }
            }
            
            binding.cbUserPreview.setOnClickListener { v ->
                val userPosition = bindingAdapterPosition
                if (userPosition != RecyclerView.NO_POSITION) {
                    if (!onCheckChanged(userPosition)) {
                        binding.cbUserPreview.toggle()
                    }
                }
            }
        }

        private fun onCheckChanged(userPosition: Int): Boolean {
            val userInfo: UserInfo = getItem(userPosition)
            val isSelected: Boolean = isSelected(userInfo)

            if (!isSelected) {
                val totalSelectionCount = selectedUserIdList.count()
                if (totalSelectionCount == maxSelectionCount) {
                    if (maxSelectionCount == 1) {
                        // for single selection, replace previous selection
                        selectedUserIdList.removeFirst()?.let { userId ->
                            val removedIndex = userList.indexOfFirst { it.userId == userId }
                            if (removedIndex != RecyclerView.NO_POSITION) {
                                notifyItemChanged(removedIndex)
                            }
                        }
                    } else {
                        // for multiple selection, prevent additional selection
                        return false
                    }
                }
                selectedUserIdList.add(userInfo.userId)
            } else {
                selectedUserIdList.remove(userInfo.userId)
            }

            // listener to allow CreateChannelFragment to receive events when user selection is changed
            // so that the header's right button can be enabled/disabled accordingly
            onUserSelectChangedListener?.onUserSelectChanged(selectedUserIdList, isSelected)
            return true
        }

        override fun bind(item: UserInfo) {
            // bind view holder
        }
    }
}

Custom view for selection

Copy link

The XML layout for the custom user selection is defined as follows.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/vgUserItem"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="@dimen/sb_size_16"
    android:paddingTop="@dimen/sb_size_10"
    android:paddingRight="@dimen/sb_size_16"
    android:paddingBottom="@dimen/sb_size_10"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/ivUserCover"
        android:layout_width="@dimen/sb_size_36"
        android:layout_height="@dimen/sb_size_36"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/tvNickname"
        android:layout_width="@dimen/sb_size_0"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/sb_size_16"
        android:layout_marginRight="@dimen/sb_size_16"
        app:layout_constraintLeft_toRightOf="@+id/ivUserCover"
        app:layout_constraintRight_toLeftOf="@+id/cbUserPreview"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

    <androidx.appcompat.widget.AppCompatCheckBox
        android:id="@+id/cbUserPreview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

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