Question

My app is currently targeted at Android 1.6. It contains a ListView with CHOICE_MODE_SINGLE. All the items implement Checkable. I am using setItemChecked(int position, boolean value) to check/uncheck items as needed. It works as expected on Android 2.1, 2.2 and 2.3. On Android 1.6 however, no item gets checked.

Code looks like this:

Integer checkedIndex = 0; // This is actually set from somewhere else.

void updateCheckedItem() {
  int count = adapter.getCount();
  for (int i = 0; i < count; i++) {
    listView.setItemChecked(i, isChecked(i));
  }

  // Here, we should have a checked item (unless checkedIndex was null)
  SparseBooleanArray checkedPositions = listView.getCheckedItemPositions();
  int size = checkedPositions.size();
  // On Android 1.6, size is 0 (wrong)
  // On Android 2.x, size is 1 (correct)

  // Another try...
  int checkedPosition = listView.getCheckedItemPosition();
  // On Android 1.6, checkedPosition is INVALID_POSITION (-1), meaning nothing is checked (wrong)
  // On Android 2.x, checkedPosition is whatever checkedIndex is (correct)
}

boolean isChecked(int position) {
  return checkedIndex != null && checkedIndex == position;
}

This question resolved the problem by setting ListView's ChoideMode in code, not XML. I did that in code to begin with and putting it in XML made no difference for me. Problem still occurs.

How can I make this work on Android 1.6?

Was it helpful?

Solution

Found the problem. There was a change in setItemChecked() between 1.6 and 2.1.

1.6 would always clear the checked items when setItemChecked() was called with value false. So unless the last item was the checked one, it would end up with a cleared array, hence no checked items.

It can be circumvented by only calling setItemChecked for the checked item. Unchecking the other items is (obviously) handled by the ListView. If no item is to be checked (checkedIndex is null), we should use clearChoices() to make sure nothing is checked. That is useful in cases where the checked item was removed from the list and another item takes the position. If we don't clear the choice, the ListView would check that position although checkedIndex is null.

void updateCheckedItem() {
  if (checkedIndex != null) {
    listView.setItemChecked(selected, true);
  } else {
    listView.clearChoices();
  }
}

OTHER TIPS

One problem might be in getCheckedItemPositions()

It says:

Returns the set of checked items in the list. The result is only valid if the choice mode has not been set to CHOICE_MODE_NONE.

So probably better to get checked item id/position using on item click listner.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top