Как я могу избежать выполнения onTextChanged в Android EditText
Как я могу избежать такой строки кода, как:
((EditText) findViewById(R.id.MyEditText)).setText("Hello");
Вызвать событие здесь:
((EditText) findViewById(R.id.MyEditText)).addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
// HERE
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
Я хочу знать, есть ли способ заблокировать выполнение onTextChanged, как я заметил, в случае выбора выпадающего списка AutoCompleteTextView (не выполняется onTextChanged!).
Я не ищу обходные пути, например "если привет ничего не делает"...
Ответы
Ответ 1
Источник AutoCompleteTextView показывает, что они устанавливают логическое значение, чтобы сказать, что текст заменяется завершением блока
mBlockCompletion = true;
replaceText(convertSelectionToString(selectedItem));
mBlockCompletion = false;
Это так же хорошо, как любой, чтобы достичь того, что вы хотите сделать.
Затем TextWatcher проверяет, прошел ли setText через завершение и возвращается из метода
void doBeforeTextChanged() {
if (mBlockCompletion) return;
Добавление и удаление TextWatcher потребует больше времени для приложения
Ответ 2
Я поставил ту же проблему. Я решил проверить, какой вид в настоящее время имеет фокус, чтобы различать события, вызванные пользователем и программой.
EditText myEditText = ((EditText) findViewById(R.id.myEditText));
myEditText.addTextChangedListener(new TextWatcher()
{
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
if(getCurrentFocus() == myEditText)
{
// is only executed if the EditText was directly changed by the user
}
}
//...
});
Ответ 3
Я не думаю, что есть простой способ отключить прослушиватель, но вы можете обойти его:
- Удаление
TextWatcher
перед установкой текста и добавлением его после.
- Или установите флаг
boolean
перед установкой текста, который сообщает TextWatcher
игнорировать его.
например.
boolean ignoreNextTextChange = true;
((EditText) findViewById(R.id.MyEditText)).setText("Hello");
И в вашем TextWatcher
:
new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
/*
If the flag is set to ignore the next text change,
reset the flag, and return without doing anything.
*/
if (ignoreNextTextChange){
ignoreNextTextChange = false;
return;
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
Это немного взломанный, но он должен работать:)
Ответ 4
Альтернативным способом достижения этого будет использование setOnKeyListener
.
Это будет срабатывать только тогда, когда пользователь нажимает клавишу, а не всякий раз, когда EditText изменяется пользователем или программно.
myEditText.setOnKeyListener(new EditText.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch(event.getAction()) {
case KeyEvent.ACTION_DOWN:
// beforeTextChanged
break;
case KeyEvent.ACTION_UP:
// afterTextChanged
break;
}
return false;
}
});
Ответ 5
Только два способа увидеть
- вы проверяете внутри слушателя
- вы добавляете/удаляете слушателя в соответствии с определенными условиями
В качестве первого способа является нежелательным обходным путем для вас. Я боюсь, что вы работаете со вторым способом.
Ответ 6
В качестве альтернативы вы можете просто использовать mEditText.hasFocus()
, чтобы различать текст, измененный человеком или измененный программой, это отлично работает для меня:
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
if (mEditText.hasFocus()) {
// Do whatever
}
}
Надеюсь, это поможет!