3

I am trying to:

Get selected checked checkbox item in my fragment

What I have Tried

So, as I know there are 2 ways of saving state of checked box while scrolling in recyclerview

  • Using SparseBooleanArray ()
  • Using your model to save the state

I went for option 1.

Model - Songs.kt

data class Songs(
val songId: Int? = null,
) 

Adapter - SelectSongAdapter.kt

//In OnBindViewHolder - 
binding.checkbox.isChecked = checkBoxStateArray.get(position, 
false)

//function to get all checked songs
 fun getSelectedIds(): SparseBooleanArray {
    return checkBoxStateArray
}

 //In adapter viewHolder
checkbox.setOnClickListener {
if (!checkBoxStateArray.get(bindingAdapterPosition, false)).  
{//checkbox checked
checkbox.isChecked = true
//stores checkbox states and position
checkBoxStateArray.put(bindingAdapterPosition, true)
} else {//checkbox unchecked
checkbox.isChecked = false
//stores checkbox states and position.
checkBoxStateArray.put(bindingAdapterPosition, false)
 }
}

Fragment - SelectSongFragment.kt

 //get selected items - this returns an empty list, even when some 
 items are checked
 
 val selectedRows = selectSongsAdapter.getSelectedIds()
 Log.e("selectedSongs", selectedRows.toString()) 

QUESTION

How to get the selected items from adapter to fragment. My code is returning an empty list.

I want to get any checked/selected item from the adapter to my fragment (observing changes)

Zain
  • 37,492
  • 7
  • 60
  • 84
Ibccx
  • 105
  • 3
  • 11

2 Answers2

0

You shouldn't use setOnClickListener on CheckBox's, instead you need to use setOnCheckedChangeListener which has isChecked callback parameter.

Also, don't set CheckBox value programmatically within the adapter as this should be triggered by the user

So replace:

checkbox.setOnClickListener {
    if (!checkBoxStateArray.get(bindingAdapterPosition, false)).{//checkbox checked
        checkbox.isChecked = true
        //stores checkbox states and position
        checkBoxStateArray.put(bindingAdapterPosition, true)
    } else {//checkbox unchecked
        checkbox.isChecked = false
        //stores checkbox states and position.
        checkBoxStateArray.put(bindingAdapterPosition, false)
}

With:

checkbox.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
    checkBoxStateArray.put(bindingAdapterPosition, isChecked)
})
Zain
  • 37,492
  • 7
  • 60
  • 84
  • Hello. I read from a comment that its not safe using onCheckedChangeListner. https://stackoverflow.com/a/41843879/15985008 I have replaced but my issue remains: Getting selected item in my fragment – Ibccx May 21 '21 at 05:30
0
  • Pass a call back function in your constructor of the adapter class itemCheckListener: (isChecked: Boolean, data: MutableList) -> Unit

  • get data if isChecked is true

// make it global and you can use any class instead of the string class

 private val data = mutableListOf<String>()

 holder.binding.isChecked.setOnCheckedChangeListener { _, isChecked ->
            data.add(getItemPosition)
            itemCheckListener(isChecked, data)
        }
  • Using it in your in your fragment

//get data

val myAdapter: MyAdapterClass by lazy {
                MyAdapterClass { isActive, data->
                    Log.d("CLICKS", "YOU CLICK  FRAGMENT $data")}
            }
Kwesi Welbred
  • 69
  • 1
  • 5