use*_*767 88 java android event-handling infinite-loop
我有一个EditText带有客户文本观察器的字段.在一段代码中,我需要更改我使用的EditText中的值.setText("whatever").
问题是,一旦我进行了更改,afterTextChanged调用的方法就会创建一个无限循环.如何在不触发afterTextChanged的情况下更改文本?
我需要在afterTextChanged方法中的文本,所以不建议删除TextWatcher.
Wil*_*zel 94
您可以检查当前哪个View具有焦点,以区分用户和程序触发的事件.
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
}
}
//...
});
Run Code Online (Sandbox Code Playgroud)
编辑:正如LairdPleng正确提到的,如果myEditText已经有焦点并且您以编程方式更改文本,则此方法无效.因此,在调用之前clearFocus()你应该叫setText(...)为焯芬表示,这解决了这个问题为好.
Cha*_*Him 26
public class MyTextWatcher implements TextWatcher {
private EditText et;
// Pass the EditText instance to TextWatcher by constructor
public MyTextWatcher(EditText et) {
this.et = et;
}
@Override
public void afterTextChanged(Editable s) {
// Unregister self before update
et.removeTextChangedListener(this);
// The trick to update text smoothly.
s.replace(0, s.length(), "text");
// Re-register self after update
et.addTextChangedListener(this);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
et_text.addTextChangedListener(new MyTextWatcher(et_text));
Run Code Online (Sandbox Code Playgroud)
如果您使用editText.setText()而不是editable.replace(),则在快速输入文本时可能会感到有点滞后.
Jef*_*man 14
很容易修复... 只要你的逻辑推导出新的编辑文本值是幂等的(它可能会,但只是说).在侦听器方法中,如果当前值与上次修改值不同,则仅修改编辑文本.
例如,
TextWatcher tw = new TextWatcher() {
private String lastValue = "";
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
// Return value of getNewValue() must only depend
// on the input and not previous state
String newValue = getNewValue(editText.getText().toString());
if (!newValue.equals(lastValue)) {
lastValue = newValue;
editText.setText(newValue);
}
}
};
Run Code Online (Sandbox Code Playgroud)
您可以使用 Kotlin DSL 语法来获得通用解决方案:
fun TextView.applyWithDisabledTextWatcher(textWatcher: TextWatcher, codeBlock: TextView.() -> Unit) {
this.removeTextChangedListener(textWatcher)
codeBlock()
this.addTextChangedListener(textWatcher)
}
Run Code Online (Sandbox Code Playgroud)
在您的 TextWatcher 中,您可以将其用作:
editText.applyWithDisabledTextWatcher(this) {
text = formField.name
}
Run Code Online (Sandbox Code Playgroud)
我用这种方式:
mEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
if (mEditText.isFocused()) { //<-- check if is focused
mEditText.setTag(true);
}
}
});
Run Code Online (Sandbox Code Playgroud)
并且每次需要以编程方式更改文本时,请先清除焦点
mEditText.clearFocus();
mEditText.setText(lastAddress.complement);
Run Code Online (Sandbox Code Playgroud)
使用filed 可以轻松解决该问题tag,您甚至不必处理editText 的焦点。
以编程方式设置文本和标签
editText.tag = "dummyTag"
editText.setText("whatever")
editText.tag = null
Run Code Online (Sandbox Code Playgroud)
检查tagonTextChanged 中的
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (editText.tag == null) {
// your code
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
这对我很有用
EditText inputFileName; // = (EditText)findViewbyId(R.id...)
inputFileName.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
//unregistering for event in order to prevent infinity loop
inputFileName.removeTextChangedListener(this);
//changing input's text
String regex = "[^a-z0-9A-Z\\s_\\-]";
String fileName = s.toString();
fileName = fileName.replaceAll(regex, "");
s.replace(0, s.length(), fileName); //here is setting new text
Log.d("tag", "----> FINAL FILE NAME: " + fileName);
//registering back for text changes
inputFileName.addTextChangedListener(this);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
public void onTextChanged(CharSequence s, int start, int before, int count) { }
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
46433 次 |
| 最近记录: |