Android:过滤列表视图时检查了错误的项目

发布于 2024-12-11 10:53:43 字数 1787 浏览 0 评论 0 原文

我遇到了与此问题相同的问题:错误的项目检查时在android中过滤ListView

正如上面的问题所建议的,我有一个包含所有selectedId的哈希集,但我不知道当光标重新填充选中的项目时如何使用它。

我的问题只是装饰性的 - 例如:

  • “Facebook”位于未过滤列表中的第五个位置。
  • 用户搜索“face”,只有“Facebook”出现在过滤列表的第一个位置。
  • 用户选中“Facebook”作为选择并返回到未过滤列表。
  • 选中的项目是列表中的第一项,而不是“Facebook”(位于第五位)。

注意: 除了这个问题,其他都很好。 例如,“删除”将删除正确的项目,因为我使用 selectedId 来执行此操作(即使选中的项目是错误的)。

单击列表项:

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));

将不胜感激任何帮助!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

王权女流氓 2024-12-18 10:53:43

难道只是因为你的ListView不知道数据集发生了变化?在适配器上调用notifyDatSetChanged()以使其知道。

my_adapter.notifyDataSetChanged();

这将强制使用更新的数据重新绘制列表。

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.

娇妻 2024-12-18 10:53:43

解决了问题。
正如我添加到我的问题中所建议的,当您填充复选框时,其他列表/哈希集应确定是否将项目标记为已选中。

使用我的代码:

//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);
}

真的希望这对任何人都有帮助! :)

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! :)

述情 2024-12-18 10:53:43

这是我的解决方案:

  • 要在过滤后在列表视图中选择一个项目,一开始,我得到了错误的项目,因为我使用了这个:

    ItemData item = listItems.get(position);
    

正确的方法应该是这样的:

    ItemData item = (ItemData) parent.getItemAtPosition(position);
  • 要在过滤后删除一个项目,我已经尝试过这个:

    for(int i=0;i

但这不起作用,因为我的自定义适配器。在我的自定义适配器中,要使用过滤器,我有两个列表项:

    ArrayList<ItemData> listItemsToShow = new ArrayList< ItemData >();
    ArrayList< ItemData > listItemsBackup = new ArrayList< ItemData >();

因此要删除一个项目,我在自定义适配器中添加了新方法:

    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();

希望有帮助

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文