Как избежать множественных триггеров в EditText во время ввода пользователем?

Я использую следующий код для выполнения поиска, когда пользователь вводит в EditText:

EditText queryView = (EditText) findViewById(R.id.querybox); queryView.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { triggerSearch(s.toString()); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } }); 

Однако это срабатывает несколько раз, когда пользователь вводит слово. То есть, если пользователь вводит «привет», этот код будет вызывать 5 раз со значениями («h», «he», «hel», «hell», «hello»). Как правило, это было бы хорошо, но запуск поиска был дорогостоящим, и я не хочу тратить ресурсы на промежуточные поиски, которые не очень полезны. То, что я хочу, это либо слушатель, который запускает только определенный порог после того, как пользователь начинает вводить текст, либо какой-то фреймворк, который ждет в слушателе перед вызовом triggerSearch , и если другое событие запускается до этого ожидания, отменяет себя.

Solutions Collecting From Web of "Как избежать множественных триггеров в EditText во время ввода пользователем?"

Поскольку не удалось найти подходящий интерфейс событий, попробуйте запустить задержку поиска. Код на самом деле довольно простой и надежный.

 private final int TRIGGER_SERACH = 1; // Where did 1000 come from? It's arbitrary, since I can't find average android typing speed. private final long SEARCH_TRIGGER_DELAY_IN_MS = 1000; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == TRIGGER_SERACH) { triggerSearch(); } } }; queryView.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { } @Override public void afterTextChanged(Editable s) { handler.removeMessages(TRIGGER_SERACH); handler.sendEmptyMessageDelayed(TRIGGER_SERACH, SEARCH_TRIGGER_DELAY_IN_MS); }); 

Одно из решений заключалось бы в том, чтобы немедленно выполнить ваш инициированный поиск, но через некоторый интервал, скажем, 100 мс, прошел с момента onTextChanged метода onTextChanged . Кроме того, сбрасывайте этот интервал каждый раз, когда набирается текст.

Таким образом, вызванный поиск не вызывается во время ввода пользователем.

triggerSearch в слушателе перед вызовом triggerSearch ; Проверьте длину Editable s .

if(s.length() > THRESHOLD)

Если вы не хотите запускать поиск на каждой нажатой кнопке, вам нужно знать, когда пользователь будет выполнен. Я бы избегал сложных идей по попытке выяснить, когда пользователь набирает текст. Это приведет к тому, что пользователь будет смущен, когда произойдет поиск.

Простой ответ затем помещается кнопкой «done» и накладывает onClickListener на кнопку и выполняет поиск там.

Самый простой код: в xml

 <Button android:onClick="onDoneClicked" ... the rest of your button layout /> 

В java:

 @Override public void onDoneClicked(View view){ EditText queryView = (EditText) findViewById(R.id.querybox); triggerSearch(queryView.toString()); }