首页 > 解决方案 > 为什么在搜索项目期间我的回收站视图适配器清除?

问题描述

我想从回收站视图中搜索项目。我有 MainActivity,我有主回收器视图,我有 SearchActivity,我有秒回收器视图,用于显示搜索项目。当用户在输入中输入一个字母时,我会向我的 SQLite 询问与我的输入文本相同的查询。如果我的 SQLite 给了我数据,我将这些数据插入到第二个回收器视图中,并显示给用户。这是我的代码:

// onCreate() method
 initRecyclerView(); // init empty recycler view

    EditText et_input = getActivity().findViewById(R.id.et_search_for_task_input);
    et_input.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged (CharSequence s, int start, int count, int after) {
            // nothing...
        }

        @Override
        public void onTextChanged (CharSequence s, int start, int before, int count) {
            if (count == 0) { // if empty I show to user nothing
                adapter.clearAll();
                adapter.notifyDataSetChanged();
            } else {
                Cursor cursor = database.rawQuery("SELECT * FROM todo WHERE task LIKE '%" + String.valueOf(s) + "%'", null); // ask for data from database

                if (cursor.moveToFirst()) { // if the response wasn't empty
                    do {
                    // add filter data in adapter and save adapter(notifyDataSetChanged();)
                        adapter.addTask(cursor.getString(cursor.getColumnIndex("task"))); 
                        adapter.notifyDataSetChanged();
                    } while (cursor.moveToNext());
                }

                cursor.close();
            }
        }

        @Override
        public void afterTextChanged (Editable s) {
           // adapter.clearAll();
        }
    });

一切正常。但我有问题。当用户输入一个字母时,他会得到一个搜索项目列表,如果他想在输入中添加或删除文本,他会得到一个包含旧搜索项目的新搜索项目列表。所以,我需要从适配器中删除旧的搜索项。我该怎么做????我一直在尝试做下一个:在 afterTextChanged 方法中调用 adapter.clearAll();。我希望当用户完成输入他的数据时,这些数据会添加到适配器中,并且适配器会在不更新回收器视图(notifyDataSet...();) 的情况下清除,并且当他搜索另一个时,他会获得新的搜索项目列表而没有旧的搜索项目。但是我什么都没有!!!请帮帮我!我希望我能告诉你我的问题,你能理解我:)

标签: javaandroidandroid-recyclerview

解决方案


目前还不是很清楚你的问题到底是什么,但从我的想法来看:

  • 每次用户键入一个字符时,onTextChanged都会触发另一个事件,并且由于您没有清除中间的适配器,显然您的addTask条目会累积。
  • afterTextChanged之后被调用onTextChanged,所以如果你在填充后立即清除适配器,它最终会为空。我不确定是否notifyDataSetChanged立即重绘 RecyclerView 或将其排队,但很可能另一个 notifyDataSetChanged 可能会在期间adapter.clearAll或其他地方潜入,让您的视图为空。您应该在重新填充之前立即清除适配器,而不是之后。
  • 您不需要notifyDataSetChanged在每个addTask. 添加当前迭代的所有任务,然后调用notify...一次。
  • 如果您继续阅读,ontextChanged您会发现,count参数中仅显示更改了多少个字符(或者更确切地说,当前键入的单词或 smth 中有多少个字符),使用它来检测是否CharSequence s为空并不是最佳选择。而是检查CharSequence s.

所以你需要做的是:

    @Override
    public void onTextChanged (CharSequence s, int start, int before, int count) {
        if (s.length() == 0) { // if empty I show to user nothing
            adapter.clearAll();
            adapter.notifyDataSetChanged();
        } else {
            Cursor cursor = database.rawQuery("SELECT * FROM todo WHERE task LIKE '%" + String.valueOf(s) + "%'", null); // ask for data from database
            adapter.clearAll();
            if (cursor.moveToFirst()) { // if the response wasn't empty
                do {
                // add filter data in adapter and save adapter(notifyDataSetChanged();)
                    adapter.addTask(cursor.getString(cursor.getColumnIndex("task"))); 
                } while (cursor.moveToNext());
            }
            cursor.close();
            adapter.notifyDataSetChanged();
        }
    }

如果您的适配器按我预期的那样工作,那就应该这样做。你从来没有展示过你的 RecyclerView 适配器,所以我不知道做什么addTaskclearAll做什么。


推荐阅读