Search code examples
androidlistviewtextwatcher

reset listview after filtering


I am using a AutoCompleteTextView (will later be changing this to an editText but one problem at a time) to filter the results of my listView implementing a textWatcher:

fqp = new FilterQueryProvider() {
            @Override
            public Cursor runQuery(CharSequence constraint) {
                String itemName = constraint.toString();
                return getSearch(itemName);
            }
        };

Cursor getSearch(String itemName) {
        String searchSelect = "(" + MediaStore.Audio.Media.TITLE + " LIKE ? )";
        String[]  selectArgs = { "%" + itemName + "%"};
        Cursor searchCursor = getContentResolver().query(
                queryUri,
                projection,
                searchSelect,
                selectArgs,
                MediaStore.Audio.Media.TITLE + " ASC"
        );
        return searchCursor;
    }

public void onTextChanged(CharSequence s, int start, int before,
                              int count) {
        String empty = "";
        if(s.toString() == empty){
            adapter.changeCursor(getAll());
            adapter.notifyDataSetChanged();
        }else{
            adapter.getFilter().filter(s.toString());
            adapter.notifyDataSetChanged();
        }
    }

This filter works just fine, but i need to figure out a way to reset my list once my autoCompleteTextView is empty. Surely there is a correct way to do this other than testing if it's empty but that's what i tried to no avail. Also should i just create two Cursors: one containing my full list and the other my filtered list so i don't have to re-query the content provider?


Solution

  • The issue seems to lie in this line

    if(s.toString() == empty)
    

    In Java, you cannot compare Strings like this, you need to use

    if(s.toString().equals(empty))
    

    Also TextWatcher is not getting called because the listener is not linked to your AutoCompleteTextView.


    Also should i just create two Cursors: one containing my full list and the other my filtered list so i don't have to re-query the content provider?

    If the filtered list will have the same data every time, then yes it's better to keep a reference to it instead of doing a new query.

    Example using EditText:

    adapter.setFilterQueryProvider(fqp);
    search.addTextChangedListener(watch);
    
    fqp = new FilterQueryProvider() {
        @Override
        public Cursor runQuery(CharSequence constraint) {
            String itemName = constraint.toString();
            return getSearch(itemName);
        }
    };
    
    Cursor cursor = getContentResolver().query(
        queryUri,
        projection,
        null,
        null,
        MediaStore.Audio.Media.TITLE+" ASC"
    );
    
    Cursor getSearch(String itemName) {
        String searchSelect = "(" + MediaStore.Audio.Media.TITLE + " LIKE ? )";
        String[]  selectArgs = { "%" + itemName + "%"};
        Cursor searchCursor = getContentResolver().query(
            queryUri,
            projection,
            searchSelect,
            selectArgs,
            MediaStore.Audio.Media.TITLE + " ASC"
        );
        return searchCursor;
    }
    
    TextWatcher watch = new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                                  int count) {
            String empty = "";
            if (s.toString().equals(empty)) {
                adapter.changeCursor(cursor);
                adapter.notifyDataSetChanged();
            } else {
                adapter.getFilter().filter(s.toString());
                adapter.notifyDataSetChanged();
            }
        }
    
        @Override
        public void beforeTextChanged(CharSequence s, int start,
                                      int count, int after) {
        }
    
        @Override
        public void afterTextChanged(Editable s) {
    
        }
    };