Как избежать множественных триггеров в 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
, и если другое событие запускается до этого ожидания, отменяет себя.
Ответы
Ответ 1
Так как не удалось найти соответствующий интерфейс событий, попробуйте запустить поиск с задержкой. Код на самом деле довольно простой и надежный.
private final int TRIGGER_SERACH = 1;
// Where did 1000 come from? It 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);
});
Ответ 2
Одним из решений было бы не выполнять ваш инициированный поиск немедленно, но через некоторый интервал, скажем 100 мс, прошло с момента вызова метода onTextChanged
. Дополнительно reset этот интервал при каждом вводе текста.
Таким образом, вызванный поиск не вызывается во время ввода пользователем.
Ответ 3
Ожидание в слушателе перед вызовом triggerSearch
; проверьте длину Editable s
.
if(s.length() > THRESHOLD)
Ответ 4
Если вы не хотите запускать поиск на каждой нажатой кнопке, вам нужно знать, когда пользователь будет выполнен. Я бы избегал сложных идей по попытке выяснить, когда пользователь набирает текст. Это приведет к тому, что пользователь будет смущен, когда происходит поиск.
Простой ответ затем помещается на кнопку "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());
}