10

I have an EditText to filter the items in the ListView below it, which may contain more than 1000 items usually. The TextWatcher is:

txt_itemSearch.addTextChangedListener(new TextWatcher() {

public void onTextChanged(CharSequence s, int start, int before, int count) {
    fillItemList();
}
public void afterTextChanged(Editable s) {
}

public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
}
});

The issue here is that with each letter typed by the user, the list is getting refreshed and it's this repeated list update which causes the UI to be slow.

How can I make the TextWatcher wait for 1-2 secs and if no more input happens after 2 secs, then filter the list. Any suggestions guys?

user
  • 86,916
  • 18
  • 197
  • 190
desidigitalnomad
  • 1,443
  • 21
  • 33
  • 1
    *Any suggestions guys?* - use the proper way of filtering the `ListView` using the adapter's `getFilter()` method. – user Feb 02 '13 at 10:03
  • OK, but the filtering is kind of complex. I've also got a couple of Checkboxes and other parameters to be filtered, so my only option is to get it thru SQLite query. – desidigitalnomad Feb 02 '13 at 10:08

2 Answers2

18

How can I make the textWatcher wait for 1-2 secs and if no more input happens after 2 secs, then filter the list.

As I already said in the comment you should look into using the getFilter() method of the adapter. As that may not be suitable(as you say) try to implement the same mechanism the adapter's filter uses to cancel in between filter inputs.

private Handler mHandler = new Handler();

public void afterTextChanged(Editable s) {
      mHandler.removeCallbacks(mFilterTask); 
      mHandler.postDelayed(mFilterTask, 2000);
}

where filterTask is:

Runnable mFilterTask = new Runnable() {

     @Override
     public void run() {
          fillItemList();
     }       
}
user
  • 86,916
  • 18
  • 197
  • 190
  • when i checked LogCat now, I noticed that though the processing happens only after 2 secs, the Runnable runs many times. For eg, If I type 'sof', fillItemList runs 3 time- for 's', 'so' and 'sof'. I thought Handler.removeCallbacks would take care of it, but it didn't. – desidigitalnomad Feb 02 '13 at 11:18
  • @rbH Are you sure about that? Are you typing fast enough? – user Feb 02 '13 at 11:20
  • 1
    Oops!. My bad. I put mFilterTask inside afterTextChanged and so each time, a new runnable was being created. Smoother than milk now :) Thank you – desidigitalnomad Feb 02 '13 at 11:45
0

Using RxBinding :

RxTextView.textChanges(edittext)
            .skipInitialValue()
            .debounce(TIME_TO_WAIT, TimeUnit.MILLISECONDS)
            .subscribe({
               //do the thing
            })
}
Sermilion
  • 1,920
  • 3
  • 35
  • 54