Quick filter in Listview - Tutorial (source code download)

Updated: 09 April 2013

Tested in:
HTC desire S (android 2.3.5)

Base on:
Eclipse Indigo build in 20120216-1857, Java 1.6, Android 4.1.2

Download Source code:
DemoListViewFilter20130409.rar

Description:
Quick filter in listview by Text in rows.

Screen shot:


Tutorial:
1. Create an adapter implement android.widget.Filterable
public class SimpleAdapter extends BaseAdapter implements Filterable{}

2. Create class SimpleFilter to control the text filter
private class SimpleFilter extends Filter {
  @Override
  protected FilterResults performFiltering(CharSequence constraint) {
   FilterResults results = new FilterResults();
   // We implement here the filter logic
   if (constraint == null || constraint.length() == 0) {
    // No filter implemented we return all the list
    results.values = mCurrentList;
    results.count = mCurrentList.size();
   }
   else {
    // We perform filtering operation
    ArrayList<String> nList = new ArrayList<String>();
    for (String p : mCurrentList) {
     if (p.toUpperCase().indexOf(constraint.toString().toUpperCase()) >= 0)
      nList.add(p);
    }
    results.values = nList;
    results.count = nList.size();
   }
   return results;
  }

  @Override
  protected void publishResults(CharSequence constraint,
    FilterResults results) {
   // Now we have to inform the adapter about the new list filtered
   if (results.count == 0)
    notifyDataSetInvalidated();
   else {
    mCurrentList = (ArrayList<String>) results.values;
    notifyDataSetChanged();
   }
   }
 }

3. Handle the EditText changing to apply filter rules.
editTextFilter.addTextChangedListener(new TextWatcher() {
   @Override
   public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (s == null || s.length() == 0) {
     if (imageButtonResetFilter != null)
      imageButtonResetFilter.setVisibility(View.GONE);
    } else {
     if (imageButtonResetFilter != null)
      imageButtonResetFilter.setVisibility(View.VISIBLE);
    }
    if (count < before) {
     simpleAdapter.resetData();
    }
    simpleAdapter.getFilter().filter(s.toString());
   }

   @Override
   public void beforeTextChanged(CharSequence s, int start, int count,
     int after) {
    // TODO Auto-generated method stub
    }

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

References:
developer.android.com/reference/android/widget/Filterable.html
developer.android.com/reference/android/widget/ListView.html
developer.android.com/reference/android/widget/Adapter.html

Leave a Reply

Powered by Blogger.