Reputation: 10656
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
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
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