Question

I use addTextChangeListener to filter a list items. When the user enters a character on the editText, items are filtered based on user input. For example, if the user enters "stackoverflow", all items that contains "stackoverflow" are displayed. It works fine except that once the user press backspace to delete character(s), items are no longer filtered until he deletes all characters.

For example, my items are: "stackoverflow 1", "stackoverflow 2", "stackoverflow 3", "stackoverflow 4".

If user input is "stackoverflow", all items are displayed. If user input is "stackoverflow 1", only "stackoverflow 1" is displayed. Then user deletes the last 2 characters (1 and the space). User input is now "stackoverflow" but "stackoverflow 1" is still displayed and the other items are not displayed.

This is my custom filter:

private class ServiceFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results = new FilterResults();
            if (constraint == null || constraint.length() == 0) {
                // No filter implemented we return all the list
                results.values = origServiceList;
                results.count = origServiceList.size();
            }
            else {
                List<ServiceModel> nServiceList = new ArrayList<ServiceModel>();
                for (ServiceModel s : serviceList) {
                    if (s.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
                        nServiceList.add(s);
                    }
                }
                results.values = nServiceList;
                results.count = nServiceList.size();
            }
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            if (results.count == 0) {
                notifyDataSetInvalidated();
            }
            else {
                serviceList = (List<ServiceModel>) results.values;
                notifyDataSetChanged();
            }
        }   
    }

And how I handle text change event:

inputSearch.addTextChangedListener(new TextWatcher() {

            @Override
            public void afterTextChanged(Editable arg0) {
                // TODO Auto-generated method stub
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                // TODO Auto-generated method stub
            }

            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {

                if (cs.length() >= 1) {
                    mAdapter.getFilter().filter(cs);
                }
                else {
                    mAdapter = new ServiceAdapter(MyActivity.this, R.layout.ussd_list_item, serviceList);
                    listView.setAdapter(mAdapter);
                }
            }

        });
Was it helpful?

Solution

I would say because your filtering your existing filtered results, not the original results. So when you start to backspace, it will only search within your previous results.

Try this to see if it fixes it:

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        FilterResults results = new FilterResults();
        if (constraint == null || constraint.length() == 0) {
            // No filter implemented we return all the list
            results.values = origServiceList;
            results.count = origServiceList.size();
        }
        else {
            List<ServiceModel> nServiceList = new ArrayList<ServiceModel>();
            for (ServiceModel s : origServiceList) {
                if (s.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
                    nServiceList.add(s);
                }
            }
            results.values = nServiceList;
            results.count = nServiceList.size();
        }
        return results;
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top