I feel rather stupid for not noticing this before but when I scroll up and down in my app, the checkboxes randomly check and uncheck. The checkboxes are on the GroupView and not the Child element of the Expandable ListView. I have done a lot of research into this and realise that the problem is recycling views and something to do with the onCheckedChangeListener. I also know (sort of) what I have to do to solve the problem. Thing is, I am not sure how to implement it. This is because all research leads to fixes for people using checkboxes ListView or fixes for checkboxes in the ChildView of an Expandable ListView
Here is the tutorial I used for Expandable ListView
Below are other links I have found relating to my issue, sort. None of them can particularly help:
Android ListView with Checkbox: automatically unchecks
Android, Checkboxes Randomly Checked/Unchecked in Expandable List
checkbox unchecked when i scroll listview in android
ListView with CheckBox Scrolling Issue
Expandable listview with selectall checkbox : group itemclick and scrolling bug
Below is some code that I hope will shed some light on things:
ExpandableListAdapter.java: Now updated based on first answer
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;
boolean checkAll_flag = false;
boolean checkItem_flag = false;
public ExpandableListAdapter(Context context, List<String> listDataHeader,
HashMap<String, List<String>> listChildData) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listChildData;
}
@Override
public Object getChild(int groupPosition, int childPosititon) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.get(childPosititon);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.suikoden_list_item1, null);
}
TextView txtListChild = (TextView) convertView
.findViewById(R.id.lblListItem);
txtListChild.setText(childText);
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size();
}
@Override
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
@Override
public int getGroupCount() {
return this._listDataHeader.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
class ExpanableValue
{
String title;
boolean isChecked;
// setter and getter
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.suikoden_list_group1, null);
//convertView.setTag(gholder);
//}else{
//gholder = (GroupViewHolder)convertView.getTag();
}
/////////////////////
CheckBox cb = (CheckBox)convertView
.findViewById(R.id.checkboxTick);
cb.setTag(groupPosition);
cb.setOnClickListener(this);
cb.setCheck(groupList.get(groupPosition).isChecked());
////////////////////
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.lblListHeader);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(groupList.get(groupPosition).getTitle());
return convertView;
}
public void onClick(View v) {
switch(v.getId())
{
case R.id.checkboxTick:
int pos = (Integer) arg0.findViewById(R.id.checkboxTick).getTag();
groupList.get(pos).setChecked((CheckBox)v.isChecked());
break;
}
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
CheckBox in SuikodenFragment.java:
@Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
CheckBox checkBox = (CheckBox) expListView.findViewById(R.id.checkboxTick);
checkBox.setOnCheckedChangeListener(null);
if (isChecked)
// Add the tick to the box
//Log.d(TAG, "Tick the box");
checked = true;
else
// Remove the tick in the box
//Log.d(TAG, "Untick the box");
checked = false;
}
If anyone could suggest a fix, or provide sample code or any other help that would be great! Thanks in advance!