问题描述
我遭受了同样的问题,因为这个问题:错误在Android
中过滤ListView时检查项目如上所述,我有一个锁定所有所选ID的哈希集,但是当光标重新填充所检查的项目时,我无法弄清楚如何使用它.
我的问题只是化妆品 - 例如:
- "Facebook"位于未过滤列表中的第5个位置.
- 用户搜索"face",只有"Facebook"出现在过滤列表中的第1个位置.
- 用户按选定检查"Facebook",然后返回未过滤的列表.
- 已选中的项目是列表中的第一个项目而不是"Facebook"(第5位).
注意: 除了这个问题,其他一切都有效. 例如,"删除"将删除正确的项目,因为我使用所选ID来执行它(即使选中的项目是错误的).
单击列表项:
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); } } };
在光标内: - 这是问题所在的地方.
这重新划分了选中的项目 - 问题是它按位置(POS)是这样的,并且过滤列表中项目的正确位置是什么,它不是它在未过滤列表中的位置 - 导致错误标记的项目.
CheckedTextView markedItem = (CheckedTextView) row.findViewById(R.id.btitle); markedItem.setChecked(checkedStates.get(pos));
将欣赏任何帮助!
推荐答案
解决了这个问题. 如图所示,在我添加到我的问题中,当您填充复选框时,其他列表/散列必须确定是否将项目标记为选中.
使用我的代码:
//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); }
真的希望这将有助于任何人! :)
其他推荐答案
可以简单地说明您列表view不知道数据集已更改?调用适配器上的NotifyDatsetchanged()以使其了解.
my_adapter.notifyDataSetChanged();
这将强制列表的重绘,使用更新的数据.
其他推荐答案
这是我的解决方案:
-
在筛选后在列表视图中选择一个项目,在开始时,我遇到了错误的项目,因为我使用了这个:
ItemData item = listItems.get(position);
正确的方式应该是这样的:
ItemData item = (ItemData) parent.getItemAtPosition(position);
-
要在过滤后删除项目,我已经尝试了这个:
for(int i=0;i<listItems.size();i++){ if(listItems.get(i).getItemID() == item.getItemID()){ listItems.remove(i); myAdapter.notifyDataSetChanged(); } }
但它没有工作,因为我的自定义适配器.在我的自定义适配器中,要使用过滤器,我有两个listItems:
ArrayList<ItemData> listItemsToShow = new ArrayList< ItemData >(); ArrayList< ItemData > listItemsBackup = new ArrayList< ItemData >();
要删除项目,我在Custom适配器中添加了新方法:
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; } }
最后删除列表视图中的项目:
subjectBaseAdapter.deleteItem(subject.getId()); subjectBaseAdapter.notifyDataSetChanged();
希望这有助于
问题描述
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!
推荐答案
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! :)
其他推荐答案
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.
其他推荐答案
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