Home > Blockchain >  How to use checkbox with select all in Recyclerview android
How to use checkbox with select all in Recyclerview android

Time:08-21

In my application I want use checkbox in recyclerview.
I want when users click on item check/unchecked checkbox and when click on Select All or clear, checked/unchecked all of items.
I write below codes, when click on select all checked all of checkboxes but after click on one of checkbox not unchecked!
I should click twice on checkbox after unchecked!
My UI is :
enter image description here My Adapter codes :

class DataListAdapter @Inject constructor() : RecyclerView.Adapter<DataListAdapter.ViewHolder>() {

    private lateinit var binding: ItemWithCheckboxBinding
    private lateinit var context: Context
    private var moviesList = emptyList<String>()
    private var isSelectedAll = false
    private var checkBoxState = SparseBooleanArray()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        binding = ItemWithCheckboxBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        context = parent.context
        return ViewHolder()
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(moviesList[position])

        holder.checkBox.isChecked = checkBoxState.get(position, false)

        var state: String
        if (!isSelectedAll) {
            holder.checkBox.isChecked = false
            state = LIST_STATE_REMOVE
            onItemClickListener?.let { it(moviesList[position], state) }
        } else {
            holder.checkBox.isChecked = true
            state = LIST_STATE_ADD
            onItemClickListener?.let { it(moviesList[position], state) }
        }
    }

    override fun getItemCount() = moviesList.size

    inner class ViewHolder : RecyclerView.ViewHolder(binding.root) {

        val checkBox = binding.itemCheck

        @SuppressLint("SetTextI18n")
        fun bind(item: String) {
            binding.apply {
                //Views
                itemTitle.text = item
                //Click
                var state: String
                binding.root.setOnClickListener {
                    if (!checkBoxState.get(adapterPosition, false)) {
                        checkBox.isChecked = true
                        checkBoxState.put(adapterPosition, true)
                        state = LIST_STATE_ADD
                    } else {
                        checkBox.isChecked = false
                        checkBoxState.put(adapterPosition, false)
                        state = LIST_STATE_REMOVE
                    }
                    onItemClickListener?.let { it(item, state) }
                }
            }
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    fun selectAll() {
        isSelectedAll = true
        notifyDataSetChanged()
    }

    @SuppressLint("NotifyDataSetChanged")
    fun unSelectAll() {
        isSelectedAll = false
        notifyDataSetChanged()
    }

    private var onItemClickListener: ((String, String) -> Unit)? = null

    fun setOnItemClickListener(listener: (String, String) -> Unit) {
        onItemClickListener = listener
    }

    fun setData(data: List<String>) {
        val moviesDiffUtil = NotesDiffUtils(moviesList, data)
        val diffUtils = DiffUtil.calculateDiff(moviesDiffUtil)
        moviesList = data
        diffUtils.dispatchUpdatesTo(this)
    }

    class NotesDiffUtils(private val oldItem: List<String>, private val newItem: List<String>) : DiffUtil.Callback() {

        override fun getOldListSize(): Int {
            return oldItem.size
        }

        override fun getNewListSize(): Int {
            return newItem.size
        }

        override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return oldItem[oldItemPosition] === newItem[newItemPosition]
        }

        override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return oldItem[oldItemPosition] === newItem[newItemPosition]
        }
    }
}

For control select all and clear checkboxes I write codes in Fragment:

    selectAllTxt.setOnClickListener { dataListAdapter.selectAll() }
    clearTxt.setOnClickListener { dataListAdapter.unSelectAll() }

How can I fix it?

CodePudding user response:

Try to use the !checkBox.isChecked instead of !checkBoxState.get(adapterPosition, false) when clicking:

binding.root.setOnClickListener {
    if (!checkBox.isChecked) {
        checkBox.isChecked = true
        checkBoxState.put(adapterPosition, true)
        state = LIST_STATE_ADD
    } else {
        checkBox.isChecked = false
        checkBoxState.put(adapterPosition, false)
        state = LIST_STATE_REMOVE
    }
    onItemClickListener?.let { it(item, state) }
}
  • Related