It seems to me, in your case, the size of the channel list is small enough for the usual search in the list to work quickly (the number of channels is unlikely to be in tens of thousands) and the problem is rather that the search will be performed more often than necessary. In this case, you just need to add a user input delay to start searching through channels not immediately after entering one character, but to postpone this task, say, 700 milliseconds, thereby giving the user time to enter more characters and send a search request over several characters entered.
I assume you are using TextWatcher to respond to user input. The easiest solution to do this is with the Handler class.
private Runnable delayedFiltering = null; @Override public void afterTextChanged(Editable input) { if (delayedFiltering != null) { getHandler().removeCallbacks(delayedFiltering); } delayedFiltering = new Runnable() { @Override public void run() { performFiltering(input.toString()); } } getHandler().postDelayed(delayedFiltering, 700); }
You can create a separate HandlerThread or simply use the getHandler method of your TextView . The main removeCallbacksAndMessages(null) in no case do not use removeCallbacksAndMessages(null) in the second case.
Instead of creating a new anonymous Runnable each time, you can create your own class that implements this interface, add a search field to it and update this value instead of creating a new Runnable
private class DelayedFilter implements Runnable { private String constraint; @Override public void run() { performFiltering(constraint); } } private DelayedFilter delayedFiltering = new DelayedFilter(); @Override public void afterTextChanged(Editable input) { if (delayedFiltering != null) { getHandler().removeCallbacks(delayedFiltering); } delayedFiltering.constraint = input.toString(); getHandler().postDelayed(delayedFiltering, 700); }
If you are familiar with reactive programming, then the same can be done using the RxJava and RxAndroid libraries. Sample code using the debounce method is here.