import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.SearchView; import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import java.util.Timer; import java.util.TimerTask; /** * Throttles a search action by an amount of milliseconds. * * @author Aleksandar Gotev */ public class ThrottledSearch { public interface Delegate { void onThrottledSearch(String searchTerm); } private static final int DEFAULT_DELAY = 400; private int mDelayMilliseconds; private final Delegate mDelegate; private String mSearchTerm; private Timer mTimer; private AppCompatActivity mActivity; public ThrottledSearch(AppCompatActivity activity, Delegate delegate, int milliseconds) { mActivity = activity; mDelayMilliseconds = milliseconds; mDelegate = delegate; mSearchTerm = ""; } public ThrottledSearch(AppCompatActivity activity, Delegate delegate) { this(activity, delegate, DEFAULT_DELAY); } public void onTextChanged(CharSequence charSequence) { if (mTimer != null) mTimer.cancel(); mTimer = new Timer(); mSearchTerm = charSequence.toString(); mTimer.schedule(new TimerTask() { @Override public void run() { mActivity.runOnUiThread(new Runnable() { @Override public void run() { mDelegate.onThrottledSearch(mSearchTerm); } }); } }, mDelayMilliseconds); } public void attachTo(final EditText editText) { editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { ThrottledSearch.this.onTextChanged(charSequence); } @Override public void afterTextChanged(Editable editable) { } }); } public void attachTo(final SearchView searchView) { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return true; } @Override public boolean onQueryTextChange(String newText) { ThrottledSearch.this.onTextChanged(newText); return true; } }); } }