I have an ExpandableListView backed by a BaseExpandableListAdapter. The child list items are all CheckBoxes.
I expand a group, check a checkbox, and then collapse the group. The checkbox is then unchecked.
My log output is:
-- I check the checkbox:
02-27 13:51:29.674: D/ExpandableListAdapter(3583): Option '2' CHECKED
--- I collapse the group, which unchecks the checkbox:
02-27 13:51:30.850: D/ExpandableListAdapter(3583): Option '2' UNCHECKED
As you can see, collapsing a group is calling (possibly indirectly) my OnCheckedChangedListener on all of the checkboxes in that group.
My code is:
public class TestExpandableListActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ExpandableListView elv =
(ExpandableListView) findViewById(R.id.optionsELV);
ExpandableListAdapter ela = new ExpandableListAdapter(this);
elv.setAdapter(ela);
}
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private static final String TAG = "ExpandableListAdapter";
private final String[] groups;
private final String[][] children;
private final boolean[][] childrenChecked;
private final Context context;
public ExpandableListAdapter(Context c) {
this.context = c;
groups = new String[] { "Options A", "Options B" };
children =
new String[][] {{"A", "B", "C"},{"1", "2", "3"}};
childrenChecked =
new boolean[][] {{false, false, false},{false, false, false}};
}
public View getChildView(
final int groupPos,
final int childPos,
boolean isLastChild,
View convertView,
ViewGroup parent) {
CheckBox cb = new CheckBox(context);
cb.setText(children[groupPos][childPos]);
cb.setChecked(childrenChecked[groupPos][childPos]);
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(
CompoundButton buttonView,
boolean isChecked) {
Log.d(TAG,
String.format("Option '%s' %s",
children[groupPos][childPos],
isChecked ? "CHECKED" : "UNCHECKED"));
childrenChecked[groupPos][childPos] = isChecked;
}
});
return cb;
}
public int getGroupCount() {
return groups.length;
}
public int getChildrenCount(int groupPos) {
return children[groupPos].length;
}
public String getGroup(int groupPos) {
return groups[groupPos];
}
public String getChild(int groupPos, int childPos) {
return children[groupPos][childPos];
}
public long getGroupId(int groupPos) {
return (1024 * (groupPos + 1));
}
public long getChildId(int groupPos, int childPos) {
return (1024 * (groupPos + 1)) + (childPos + 1);
}
public View getGroupView(
int groupPos,
boolean isExpanded,
View convertView,
ViewGroup parent) {
TextView tv = new TextView(context);
tv.setText(groups[groupPos]);
return tv;
}
public boolean hasStableIds() {
return true;
}
public boolean isChildSelectable(int groupPos, int childPos) {
return true;
}
}
}
My layout (note that I’ve properly set choiceMode to multipleChoice) is:
<?xml version="1.0" encoding="utf-8"?>
<ExpandableListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/optionsELV"
android:choiceMode="multipleChoice"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
Why is collapsing a group unchecking all of my checkboxes? How can I prevent this from happening?
I think I’ve found the solution — use a CheckedTextView instead of a CheckBox.
The CheckedTextView doco does say that CheckedTextView is useful in a ListView — “this is useful when used in a ListView where the it’s setChoiceMode has been set to something other than CHOICE_MODE_NONE” — but I’m pretty unclear about what the difference is between CheckBox and CheckedTextView, and on why CheckBoxes just seem to completely not work.
Can anyone tell me what the difference is between CheckBox and CheckedTextView, and why CheckBoxes function so oddly inside an ExpandableListView?