简体   繁体   中英

Android, Checkboxes Randomly Checked/Unchecked in Expandable List

Using this Expandable List checkbox example code as an baseline, I am trying to save and maintain the checkbox state. However, random checkboxes are being checked and unchecked ( triggering my OnCheckedChangeListener with the new values ) when I scroll them out of sight, minimize their group, or even minimize/maximize a nearby group!

public Object getChild(int groupPosition, int childPosition) {
    return colors.get( groupPosition ).get( childPosition );
}

public long getChildId(int groupPosition, int childPosition) {
    return (long)( groupPosition*1024+childPosition );  // Max 1024 children per group
}

public View getChildView(final int groupPosition, final int childPosition, 
        boolean isLastChild, View convertView, ViewGroup parent) {

    View v = null;
    if( convertView != null ) {
        v = convertView;
    } else {
        v = inflater.inflate(R.layout.child_row, parent, false); 
    }

    Color c = (Color)getChild( groupPosition, childPosition );

    TextView color = (TextView)v.findViewById( R.id.childname );
    if( color != null ) {
        color.setText( c.getColor() );
    }

    TextView rgb = (TextView)v.findViewById( R.id.rgb );
    if( rgb != null ) {
        rgb.setText( c.getRgb() );
    }

    CheckBox cb = (CheckBox)v.findViewById( R.id.check1 );
    cb.setChecked( c.getState() );
    cb.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
        {
            colors.get(groupPosition).get(childPosition).setState(isChecked);
            context.setColorBool(groupPosition, childPosition, isChecked);
            Log.d("ElistCBox2", "listitem position: " +groupPosition+"/"+childPosition+" "+isChecked);
        }
    });

    return v;
}

I don't know what piece of code could be responsible for this, so any suggestions on what to include here are welcome. My code only differs from the original in my attempt to save the values.

my guess is that as your adapter is creating views, the check listener is being called as the checkbox view is initialized. a lot of widgets in android work like this ... the listener is called when the view is initialized.

i don't know why things work like this, but it might be to allow the client code to initialize itself in a consistent way. eg, whether the checkbox is checked by the user or whether it is initialized as checked, run the same code.

to counteract this, you can try doing something like setting a flag in your listener class impl to allow you to ignore the first click, something like,

cb.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
        private void first = true;

        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
        {
            if (first) {
              first = false;
              return;
            }

            colors.get(groupPosition).get(childPosition).setState(isChecked);
            context.setColorBool(groupPosition, childPosition, isChecked);
            Log.d("ElistCBox2", "listitem position: " +groupPosition+"/"+childPosition+" "+isChecked);
        }
    });

also, ensure that you are correctly re-using convertView in your implementation of getView() in your adapter. eg,

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (view == null) {
        view = inflater.inflate(R.layout.applications_item, null);
    }

This is a very old question, but I struggled with the same problem so here is my answer for anybody looking:

The simplest way is to use CheckBox.onClickListener instead of onCheckedChangeListener.

This is only mildly annoying in terms of rearranging your logic, but will ensure that when the boxes are unchecked randomly (by, eg expanding an adjacent group) the event will not fire.

Honestly I think this should be considered a bug, even though I'm sure the behaviour can be explained from the Android source.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM