Retrieve Selected Items on Checkable ListView: Differences in SDK Level 7 and 8
2 min read
2 min read
I'm currently testing my Android app that I'm developing for my MSc thesis on different real devices. While I own a Nexus One with Android Froyo 2.2 installed (SDK Level 8) I got now another device, an HTC Hero with a slightly older version, namely v2.1-update1 (Level 7).
And while doing some tests I observed an interesting behavior when working with checkable ListViews, basically those where you set the "choice mode" toListView.Choice_MODE_MULTIPLE
. I use this for giving the possibility to tag some items. The user gets a list of available tags on which he can select multiple ones and once he closes the activity, I collect the selected items and update the underlying data accordingly.getCheckedItemIds()
which returns an array of type long[]
containing all of the ids of the selected tags.long[] selectedIds = getListView().getCheckedItemIds();This is really handy since you can now just call your DB access layer and update your data with the given ids. Sadly this method is not supported on SDK level 7. So if you need to be backward compatible you better don't use this method, but instead there is apparently a similar one,
getCheckItemIds()
(I thought). However, using it resulted in strange side effects. It seemed as if not only the active items but also those which were active at startup of the dialog but which have then become inactive later due to the user's interaction. In fact, looking at the new API level 8 ListView method you'll find it to be depreciated with a commentOld behavior was buggy, but would sort of work for adapters without stable IDs.Having stable ids, it didn't work for me, so I coded the solution myself:
Fall back to it to support legacy apps.
private long[] getCheckedItemsIdsFix(){
SparseBooleanArray checkItemPositions = getListView().getCheckedItemPositions();
int checkedPositionsCount = checkItemPositions.size();
long[] checkedIds = new long[checkedPositionsCount];
int checkedCount = 0;
for (int i = 0; i < checkedPositionsCount; i++) {
if(checkItemPositions.valueAt(i)){
checkedIds[checkedCount++] = getListAdapter().getItemId(checkItemPositions.keyAt(i));
}
}
//check whether the size matches, otherwise shrink the array.
if(checkedCount == checkedPositionsCount)
return checkedIds;
else{
final long[] adjustedIdsArray = new long[checkedCount];
System.arraycopy(checkedIds, 0, adjustedIdsArray, 0, checkedCount);
return adjustedIdsArray;
}
}