问题
I'm suffering from the same issue as this question: Wrong item checked when filtering ListView in android
As suggested in the above question, I have an Hashset holding all the selectedIds, but I can't figure out how to use it when the cursor is repopulating the checked items.
My issue is only cosmetic - for example:
- "Facebook" is located at the 5th position in the unfiltered list.
- User searched for "face", only "Facebook" appears in the 1st position in the filtered list.
- User checks "Facebook" as selected and goes back to the unfiltered list.
- The checked item is the 1st item in the list and not "Facebook" (positioned 5th).
Note: Except this issue, everything else works great. For example, "delete" will delete the right items because I use the selectedIds to do it (even if the checked items are wrong).
Single click on a list item:
OnItemClickListener mOnItemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
//gets the Bookmark ID of selected position
Cursor cursor = (Cursor)parent.getItemAtPosition(position);
String bookmarkID = cursor.getString(0);
boolean currentlyChecked = checkedStates.get(position);
checkedStates.set(position, !currentlyChecked);
if (!selectedIds.contains(bookmarkID)) {
selectedIds.add(bookmarkID);
selectedLines.add(position);
} else {
selectedIds.remove(bookmarkID);
selectedLines.remove(position);
}
}
};
Inside the Cursor: - this is where the problem lies.
This repopulates the checked items - the problem is it does it by position (pos) and what was the right position of the item in the filtered list, is not its position in the unfiltered list - resulting in a wrongly marked item.
CheckedTextView markedItem = (CheckedTextView) row.findViewById(R.id.btitle);
markedItem.setChecked(checkedStates.get(pos));
Would appreciate any help!
回答1:
Could it be simply that you ListView does not know the data set changed? Call notifyDatSetChanged() on your adapter to let it know.
my_adapter.notifyDataSetChanged();
This will force a redraw of the list, with the updated data.
回答2:
Solved the issue. As suggested in the question I added to mine, when you populate the checkboxes, the other List/Hashset should determine whether to mark item as checked or not.
Using my code:
//first you will need to get the current item ID
String bookmarkID = cursor.getString(0);
//Then, check if the current ID is in the selectedIds hash/list
//If true - mark current item view as checked, else - uncheck.
CheckedTextView markedItem = (CheckedTextView) row.findViewById(R.id.btitle);
if (selectedIds.contains(new String(bookmarkID))) {
markedItem.setChecked(true);
} else {
markedItem.setChecked(false);
}
Really hope this will help anyone! :)
回答3:
This is my solution:
To selecte an item in list view after filtering, at the beginning, I got wrong item because I used this:
ItemData item = listItems.get(position);
The correct way should be like this:
ItemData item = (ItemData) parent.getItemAtPosition(position);
To delete an item after filtered, I have tried this:
for(int i=0;i<listItems.size();i++){ if(listItems.get(i).getItemID() == item.getItemID()){ listItems.remove(i); myAdapter.notifyDataSetChanged(); } }
But that didn't worked because my custom adapter. In my custom adapter, to use filter, I have two listItems:
ArrayList<ItemData> listItemsToShow = new ArrayList< ItemData >();
ArrayList< ItemData > listItemsBackup = new ArrayList< ItemData >();
So to delete an item, I added new method in my custom adapter:
public void deleteItem(String itemID) {
for (int i = 0; i < listItemsToShow.size(); i++) {
if (listItemsToShow.get(i).getId().equals(itemID)) {
listItemsToShow.remove(i);
break;
}
}
for (int i = 0; i < listItemsBackup.size(); i++) {
if (listItemsBackup.get(i).getId().equals(itemID)) {
listItemsBackup.remove(i);
break;
}
}
Finally to delete an item in list view:
subjectBaseAdapter.deleteItem(subject.getId());
subjectBaseAdapter.notifyDataSetChanged();
Hope this help
来源:https://stackoverflow.com/questions/7874668/android-wrong-item-checked-when-filtering-listview