I have a recycler view which has checkboxes as items. I want to make sure there cannot be selected more than 3 checkboxes. If 3 checkboxes are selected other checkboxes should not be selectable, only selected checkboxes should be able to be deselected. I am not sure if I need to implement that behaviour in adapter or fragment which holds adapter. This is how my adapter looks like:
class HomeAdapter(
private val listener: OnCheckBoxClickListener
) : ListAdapter<String, HomeAdapter.SurveyViewHolder>(HOME_COMPARATOR) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SurveyViewHolder {
val bind = ItemHomeBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return SurveyViewHolder(bind)
}
override fun onBindViewHolder(holder: SurveyViewHolder, position: Int) {
getItem(position)?.let { holder.bind(it) }
}
inner class SurveyViewHolder(
val binding: ItemHomeBinding
) : RecyclerView.ViewHolder(binding.root) {
fun bind(answer: String) = with(binding) {
checkBox.text = answer
}
init {
binding.checkBox.setOnCheckedChangeListener { _, isChecked ->
listener.onCheckBoxClickListener(
index = bindingAdapterPosition,
isChecked = isChecked,
answer = currentList[bindingAdapterPosition]
)
}
}
}
interface OnCheckBoxClickListener {
fun onCheckBoxClickListener(index: Int, isChecked: Boolean, answer: String)
}
companion object {
private val HOME_COMPARATOR = object : DiffUtil.ItemCallback<String>() {
override fun areItemsTheSame(oldItem: String, newItem: String): Boolean =
oldItem == newItem
override fun areContentsTheSame(oldItem: String, newItem: String): Boolean =
oldItem == newItem
}
}
}
So far, I have tried something like this in fragment:
private fun countCheckedCheckBoxes() = with(binding) {
var num = 0
for (i in 0..recyclerView.childCount) {
(recyclerView.getChildAt(i) as? CheckBox).also {
if (it?.isChecked == true) {
num += 1
}
}
}
if (num == 3) {
// TODO do something here
}
}