Skip to content Skip to sidebar Skip to footer

Listview Adapter With Many Checkboxes

I'm having some minor problems with my listview. Every item has some information and a checkbox. This shows up fine, I can select and deselect checkboxes etc etc. However I discove

Solution 1:

As said, the problem is that you are not setting the checkbox value in getView.

Also you could improve the efficiency of your code quite a bit. The first thing you should do is add the checkbox to your child view xml, instead of creating an array of them. Instead create a boolean array to store the value.

Note, I am amending this as I would for Java so there may be some things you need to change in C#.

publicclassListViewAdapterSSCCE : BaseAdapter
    {
    privatestring[] someData;
    privateint numberOfElements;
    private boolean[] checkValue;
    private LayoutInflater inflater;

    publicListViewAdapterSSCCE(Context context)
    {

        inflater = LayoutInflater.from(context);
    }

    publicvoidSetData(string[] someData)
    {
        this.someData = someData;
        this.numberOfElements = someData.Length;
    }

    publicvoidCheckAllBoxes(bool isChecked)
    {
        for (int i = 0; i < numberOfElements; i++)
            checkValue[i] = true;
    }

    publicoverride Java.Lang.Object GetItem(int position)
    {
        returnnull;
    }

    publicoverridelongGetItemId(int position)
    {
        return10;
    }

    publicoverrideint Count
    {
        get { return numberOfElements; }
    }

    publicoverride View GetView(final int position, View convertView, ViewGroup parent)
    {

        final ViewHolder holder; 

        if (convertView == null)
        {            
            convertView = inflater.Inflate(Resource.Layout.ChildrenList_item, null);

            holder = new ViewHolder();
            holder.itemBox = convertView.FindViewById<CheckBox>(Resource.Id.checkbox);
            holder.textView = convertView.FindViewById<TextView>(Resource.Id.item_data);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        itemBox = checkValue[position];    

        itemBox.setOnCheckedChangeListener(new OnCheckedChangeListener(){

            @Override
            publicvoidonCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {

                        checkValue[positon] = isChecked;

            }

        });

        textView.Text = this.someData[position];

        return convertView;
    }

    classViewHolder
    {
        CheckBox itemBox;
        TextView textView; 
    }
}

Solution 2:

You can see sample code in here to have an alternative fix for the checkbox state:

custom checkbox difficulty in android

If this post helps you, please mark this post as an answer.

Thanks.

Solution 3:

The problem probably is related in the way you handle recycled views in your adapter. Take a look at your getView and check if the CheckBox of each item you return is set correctly according to its 'model'.

Edit: I confirm. You have to set checkbox state just like you do with text of your textview. BTW I think handling Checkboxes the way you're doing it's a bad idea. The best thing you can do is to define a "model" for checkboxes (iE: a simple boolean[] can do the trick), avoiding to instantiate too many CheckBoxes. In your getView you can check the corresponding boolean and set the checkbox accordingly.

In order to check/uncheck them all, you can modify the boolean array in your checkAllBoxes then call the notifyDatasetChanged(), triggering an update on the listview, but operating only on the items actually shown :)

Solution 4:

mr_archano is right, this happens becuase you are using convertView which allows you to re-use/recycle view's that are no longer in view. Here's what you should need to do this properly:

An object to hold the state of each checkbox

Because your listview item's are being recycled, you can't rely on them to hold the correct state of your checkbox. So, you'll need some sort of object/array to hold the correct state of a checkbox for each list item.

Reading from the state management object

Then when you call GetView, you have to set the value of the checkbox to checked/unchecked based on that object/array's state.

Writing to the state management object

You need to implement some sort of OnChecked listener for each checkbox so you can correctly set the value of that checkbox in your statement management object/array.

You should try and use ViewHolder's

A ViewHolder is pretty simple. When you first create your View (not using convert view), you have to call "FindViewByID" to get the references to your Textbox and Checkbox. If you save those in a ViewHolder, you should be able to reference them directly when you use the ConvertView object, which will save on the additional calls to "FindViewByID". It's much easier to see it practice.

This tutorial does pretty much what you need: http://windrealm.org/tutorials/android/listview-with-checkboxes-without-listactivity.php

Solution 5:

I have the same problem dealing with a large list. For people who like me find here via Google, I'd like give my solution, I think it's more easy to understand. As guys pointed out, ListView reused views. So you shouldn't let the view hold your data state.

I'm using SimpleAdapter, with setting a customized ViewBinder, I found it is easy to fix this problem.

listItemAdapter.setViewBinder(newSimpleAdapter.ViewBinder() {

    publicbooleansetViewValue(View view, Object obj, String s) {

    if(view instanceofCheckBox){
        ((CheckBox)view).setChecked((Boolean)obj);
        returntrue;
    }
    returnfalse;
}
});

You need keep your checked/unchecked state in your own way.

Post a Comment for "Listview Adapter With Many Checkboxes"