为什么在搜索项目时清除回收者视图适配器?

时间:2018-10-26 16:36:24

标签: java android android-recyclerview recycler-adapter

我想从“回收者”视图中搜索物品。 我在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 ...(););当他要搜索另一个数据时,他会得到新的搜索项目列表,而没有旧的搜索项目。但是我什么都没有!!!请帮我! 希望我能告诉您我的问题,并且您可以理解我:)

1 个答案:

答案 0 :(得分:0)

目前还不清楚您的问题到底是什么,但是从我的角度来看:

  • 每次用户键入一个字符时,都会触发另一个onTextChanged事件,并且由于您不清除中间的适配器,显然addTask条目会累积。
  • afterTextChangedonTextChanged之后被调用,因此,如果在填充适配器后立即清除适配器,则适配器将为空。我不确定notifyDataSetChanged是否立即重绘RecyclerView或将其排队,但是很有可能在adapter.clearAll或其他地方潜入另一个notifyDataSetChanged或留下空的View。您应该在重新填充适配器之前立即清除适配器,而不是在之后立即清除
  • 您无需在每个notifyDataSetChanged之后致电addTask。添加当前迭代的所有任务,然后调用一次notify...
  • 如果您阅读ontextChanged会发现,参数count仅显示更改了多少个字符(或者当前输入的单词或内容中有多少个字符),而不是使用它来检测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的作用。