Mehdiway
Mehdiway

Reputation: 10656

Android - ListView with CheckBoxes get unchecked even when saving states

It's been 2 days and I'm beginning to lose hope in my programming abilities.
Here's my BaseAdapter :

private Context ctx;
private ArrayList<MultiSelectionItem> items;
private LayoutInflater layoutInflater;
private boolean[] checked;

// Constructor
public MultiSelectionSpinnerAdapter(Context ctx, ArrayList<MultiSelectionItem> items) {
    this.ctx = ctx;
    this.items = items;
    this.layoutInflater = LayoutInflater.from(ctx);

    checked = new boolean[items.size()];
    for (int i = 0; i < checked.length; i++) {
        checked[i] = true; // Notice I'm setting all checkboxes to checked !
    }
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final MultiSelectionItem item = items.get(position);

    CheckBox checkBox = (CheckBox) convertView;
    if (checkBox == null) {
        checkBox = (CheckBox) layoutInflater.inflate(R.layout.multi_selection_checkbox, parent, false);
    }

    checkBox.setText(item.getLabel());
    checkBox.setTag(Integer.valueOf(position));
    checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // isChecked is always false !!!!
            checked[(Integer) buttonView.getTag()] = isChecked;
        }
    });
    checkBox.setChecked(checked[position]);

    return checkBox;
}

CheckBoxes states get stored correctly in checked array, HOWEVER...
Even though I do checkBox.setChecked(true), isChecked parameter in the listener always contains false ! Why is that ?

CheckBox layout :

<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="?android:attr/spinnerDropDownItemStyle"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="15dp"
    android:paddingBottom="15dp"
    android:ellipsize="marquee" />

Upvotes: 0

Views: 87

Answers (2)

M-Wajeeh
M-Wajeeh

Reputation: 17284

Your adapter is perfectly fine, if your ListView's item is just CheckBox or anything Checkable then you can run into this if your ListView is using listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE) or android:choiceMode="singleChoice".

Fix is simple, just don't use any choice mode or use "multiChoice" in xml or CHOICE_MODE_MULTIPLE from Java code.

But if you are using this adapter with Spinner then you will have to trick the Spinner that you don't have any Checkable root element by placing your CheckBox inside some other layout like this:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

<CheckBox
    android:id="@android:id/text1"
    style="?android:attr/spinnerDropDownItemStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:paddingBottom="15dp"
    android:paddingTop="15dp"
    android:singleLine="true" />
</FrameLayout>

This way Spinner will call setChecked() on FrameLayout and by default check state is not propagated through UI hierarchy so everything will work as expected and you will be able to select more than on item inside Spinner's drop down.

Upvotes: 1

Kartheek
Kartheek

Reputation: 7214

Before setting the value to the Checkbox make the listener as null.

     checkBox.setOnCheckedChangeListener(null);
     checkBox.setChecked(checked[position]);
     checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // isChecked is always false !!!!
            checked[(Integer) buttonView.getTag()] = isChecked;
        }
    });
     //Your code ............

Upvotes: 0

Related Questions