How to change view of expandable list view children when parent is collapsed in Android?

559 Views Asked by At

I am implementing a selection mode in ExpandableListView. The selection toggles when I click a child. I have a CheckBox in each parent, from which I want to control the selection of all the children at once.

My problem is that when the parent is collapsed and I click its CheckBox, the app crashes due to null pointer exception because when I try to change the selection of the children, I can't find the children and get null. But everything works fine when the parent is expanded.

So, what is a good approach to tackle such kind of problem?

1

There are 1 best solutions below

0
Akshdeep Singh On BEST ANSWER

I solved by adding some lines of code without changing the previous code, so this answer may be helpful for someone who doesn't want to rewrite the code with a different approach.

In the calling Fragment or Activity, where the Adapter is being set, add:

private val isMyGroupExpanded = SparseBooleanArray()
val MyAdapterEV = AdapterEV(/* params */) { isChecked, groupPosition ->
    changeSelection(isChecked, groupPosition)
}
// record which groups are expanded and which are not
MyAdapterEV.setOnGroupExpandListener { i -> isMyGroupExpanded.put(i, true) }
MyAdapterEV.setOnGroupCollapseListener { i -> isMyGroupExpanded.put(i, false) }
// and where changing the selection of child
private fun changeSelection(isChecked: Boolean, groupPosition: Int) {
    if (isMyGroupExpanded.get(groupPosition, false)) { 
        /* change only if the group is expanded */ 
    }
}

So, the children of the collapsed group are not affected, but they are needed to be changed when the group expands, for that, add some lines of code in the Adapter:

private val isGroupChecked = SparseBooleanArray()
// inside override fun getGroupView(...
MyCheckBoxView.setOnCheckedChangeListener { _, isChecked ->
    onCheckedChangeListener(isChecked, groupPosition)
    isGroupChecked.put(groupPosition, isChecked)
}
// inside override fun getChildView(...
if (isGroupChecked.contains(groupPosition)) {
    myView.visibility = if (isGroupChecked.get(groupPosition)) View.VISIBLE else View.INVISIBLE
}