I have an EditText
field with a Customer Text Watcher on it. In a piece of code I need to change the value in the EditText which I do using .setText("whatever")
.
The problem is as soon as I make that change the afterTextChanged
method gets called which created an infinite loop. How can I change the text without it triggering afterTextChanged?
I need the text in the afterTextChanged method so don't suggest removing the TextWatcher
.
You can check which View currently has the focus to distinguish between user and program triggered events.
EditText myEditText = (EditText) findViewById(R.id.myEditText);
myEditText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (myEditText.hasFocus()) {
// is only executed if the EditText was directly changed by the user
}
}
//...
});
As an addition to the short answer:
In case myEditText
already has the focus when you programmatically change the text you should call clearFocus()
, then you call setText(...)
and after you you re-request the focus. It would be a good idea to put that in a utility function:
void updateText(EditText editText, String text) {
boolean focussed = editText.hasFocus();
if (focussed) {
editText.clearFocus();
}
editText.setText(text);
if (focussed) {
editText.requestFocus();
}
}
For Kotlin:
Since Kotlin supports extension functions your utility function could look like this:
fun EditText.updateText(text: String) {
val focussed = hasFocus()
if (focussed) {
clearFocus()
}
setText(text)
if (focussed) {
requestFocus()
}
}