Why my recycler view adapter clearing during search for items?

Danil

New Member
#1
I want to create searching for items from recycler view. I have MainActivity where I have the main recycler view and I have SearchActivity where I have the seconds recycler view for appearing of searching items. When user inputs a letter in the input I ask my SQLite for the same query as my input text. If my SQLite gives me data I insert these data in the second recycler view and appear their to user. Here is it my code:
Mã:
// 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();
        }
    });
All works good. But I have the issue. When user inputs a letter he gets a list of searching items and if he want to add or remove the text in input he gets a list of new searching items with OLD SEARCHING ITEMS. So, I need to delete old searching items from adapter. How can I do it???? I've been trying to do the next: called in afterTextChanged the method adapter.clearAll();. I hoped that when user finishs to input his data, these data adds in adapter and adapter clears without update recycler view(notifyDataSet...();) and when he will search another he gets new list of searching items without old searching items. But I have nothing!!! Help me pls! I hope I was able to tell you my problem and you can understand me :)
 

Admin

Administrator
Thành viên BQT
#2
It's not very clear what exactly is your problem, but from what I think it is:

  • Every time user types a character a new character another onTextChanged event is fired and as you don't clear adapter in-between obviously your addTask entries accumulate.
  • afterTextChanged gets called after onTextChanged, so if you clear your adapter right after you populate it it ends up empty. I'm not sure if notifyDataSetChanged redraws RecyclerView immediately or queues it, but it's quite likely another notifyDataSetChanged might sneak in during adapter.clearAll or somewhere else leaving you with empty View. You should clear adapter immediately before repopulating it, not right after.
  • You don't need to call notifyDataSetChanged after every addTask. Add all the task for current iteration, then call notify... once.
  • If you read up on ontextChanged you'll see, that count in parameters only show how many characters changed (or rather how many characters are in currently typed word or smth), it's not the best choice to use it to detect if the CharSequence s is empty. Rather check the length of CharSequence s.
So what you need to do is:
Mã:
    @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();
        }
    }
That should do it provided your adapter is working as I expect it to. You never showed your RecyclerView adapter, so I don't know what addTask and clearAll do.
 
Top