Checkbox on Expandable ListView GroupView auto-checking and unchecking when scrolling in android

本秂侑毒 提交于 2019-12-23 16:07:03

问题


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!


回答1:


create one class like:

class ExpanableValue
{
  String title;
  boolean isChecked;


  // setter and getter

}

instead of List<String> pass one List of ExpanableValue (or what ever you want call that).

then in getGroupView:

@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.checkBoxID);
    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;
}

then in onClick method:

@Override
public void onClick(View v) {

     switch(v.getId())
    {
      case R.id.checkBoxID:
        int pos = (Integer) v.findViewById(R.id.checkBoxID).getTag();
            groupList.get(pos).setChecked((CheckBox)v.isChecked());
            break;
    }
}

it is better to use ViewHolder in getGroupView,



来源:https://stackoverflow.com/questions/24229043/checkbox-on-expandable-listview-groupview-auto-checking-and-unchecking-when-scro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!