Search code examples
androidlistviewcheckboxandroid-listviewandroid-adapterview

Checkbox looses state on ListView scrolling


I have a list view with a Checkbox in every line to check many items at a time. When I scroll down the list my checkbox looses the state (that means, I cant check for example all items at a time)

I read lots of posts here and on the internet. People said that I would have to store my checkedItems in an 'ArrayList` which I already tried but it didn't work. At the moment I store the checked state in an Object together with all the other stuff of my list.

here's the code of my Adapter`:

    public class GalleryListAdapter extends BaseAdapter {
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        final ViewHolder holder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.gallery_list_item, parent, false);
            holder = new ViewHolder();
            // .. other stuff
            holder.chkbox = (CheckBox) convertView.findViewById(R.id.chkbox);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.chkbox.setChecked(documents.get(position).isChecked());
        holder.chkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    holder.chkbox.setChecked(holder.chkbox.isChecked() ? true : false);
                    documents.get(position).setChecked(holder.chkbox.isChecked() ? true : false);
            }   
        }
    }
}

After I scroll down the list my items are unchecked and documents.get(checkedItemPosition).checked is false. Does anyone know how to fix this?

edit - Solution

Thanks to the comments and answers I found a solution for my problem:

if (convertView == null) {
holder.chkbox = (CheckBox) convertView.findViewById(R.id.chkbox);
convertView.setTag(R.id.chkbox, holder.chkbox);
}

holder.chkbox.setTag(position);
holder.chkbox.setChecked(documents.get(position).isChecked());

holder.chkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        int getPosition = (Integer) buttonView.getTag();
        holder.chkbox.setChecked(buttonView.isChecked() ? true : false);
        documents.get(getPosition).setChecked(buttonView.isChecked() ? true : false);
    }
}

Solution

  • in getView method set Tag for the checkbox holder.

    holder.chkbox.setTag(object);
    

    and inside onCheckedChanged do this

     **public onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    
               Object obj = ( Object)buttonView.getTag();
               holder.chkbox.setChecked(obj.isChecked() ? true : false);
               documents.get(position).setChecked(obj.isChecked() ? true : false);
          }** 
    

    This will help you get rid of that problem ;)