Search code examples
androidkotlinandroid-recyclerviewandroid-checkbox

How to perform a check in checkbox clicking on entire recyclerview row


Now I register each checkbox click each time y press on the checkbox like this

 inner class OrdersInnerViewHolder(itemView: View): BaseViewHolder<Cart>(itemView){
        override fun bind(item: Cart, position: Int) {

            itemView.checkBox.setOnCheckedChangeListener { buttonView, isChecked ->
                item.isChecked = isChecked
                if(isChecked){
                 map.put(position,true)
                }else{
                    map.remove(position,true)
                }
            }
        }
    }

I plan to click the whole row to check or uncheck my item, now I know how to perform the click on the entire row but no how to set the checked changed listener

 inner class OrdersInnerViewHolder(itemView: View): BaseViewHolder<Cart>(itemView){
            override fun bind(item: Cart, position: Int) {

            itemView.setOnClickListener { 
                //How to perform checkbox check and uncheck clicking on the entire row instead of the checkbox ?
            }
                itemView.checkBox.setOnCheckedChangeListener { buttonView, isChecked ->
                    item.isChecked = isChecked
                    if(isChecked){
                     map.put(position,true)
                    }else{
                        map.remove(position,true)
                    }
                }
            }
        }

Since the checkbox has the checked listener I do not have a way to interact with it when clicking the whole view

I plan to let my user click the checkbox and also the whole row to select or unselect this checkbox

XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"
    android:weightSum="3"
    android:orientation="horizontal">

    <CheckBox
        android:id="@+id/checkBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/item_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_marginBottom="16dp"
        android:text="Test " />

    <TextView
        android:id="@+id/item_qty"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_weight="1"
        android:text="Qty: 2" />

    <TextView
        android:id="@+id/item_price"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_weight="1"
        tools:text="$100.00"/>

</LinearLayout>

Any ideas?


Solution

  • Add an OnClickListener to the parent view that toggles the CheckBox. The OnCheckedChangeListener will still get called in response to the parent view's click listener changing the checked state:

    itemView.setOnClickListener {
        itemView.checkBox.isChecked = !itemView.checkBox.isChecked
    }
    

    To get the parent view to look and behave correctly, you can add these to its element in the XML:

    android:background="?android:attr/selectableItemBackground"
    android:clipToPadding="false"
    android:focusable="true"
    

    IIRC, adding the OnCheckedChangeListener to the CheckBox automatically makes it clickable. You might consider setting itemView.checkBox.isClickable = false right after setting the listener so your whole list item will show the ripple effect even if you tap over the CheckBox.

    Side note: Don't forget to set the initial state of the CheckBox in onBindView:

    itemView.checkBox.isChecked = item.isChecked
    

    It will have an unpredictable state when it scrolls onto the screen, otherwise!