Android上的文本更改侦听器
我有一个情况,那里有两个领域。 Field1
和Field2
。 当Field1
改变时,我想要做的只是空的Field2
,反之亦然。 所以最后只有一个领域有内容。
Field1 = (EditText)findViewById(R.id.field1); Field2 = (EditText)findViewById(R.id.field2); Field1.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { Field2.setText(""); } }); Field2.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { Field1.setText(""); } });
它工作正常,如果我只附加addTextChangedListener
到Field1
,但是当我做这两个领域的应用程序崩溃。 显然是因为他们试图无限期地相互改变。 一旦Field1
改变它在此时清除Field2
Field2
被改变,所以它将清除Field1
等等…
有人可以build议任何解决scheme
您可以添加一个检查,只有当字段中的文本不为空时(即长度不等于0时)才能清除。
Field1.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) {} @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if(s.length() != 0) Field2.setText(""); } }); Field2.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) {} @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if(s.length() != 0) Field1.setText(""); } });
TextWatcher
文档在这里 。
也请尊重命名约定 。
我知道这是古老的,但有一天有人会再次遇到这种情况。
我有一个类似的问题,我会在EditText上调用setText,onTextChanged会在我不想要的时候调用。 我的第一个解决scheme是在调用setText()来取消侦听器所造成的破坏后编写一些代码。 但是那不是很优雅。 在做了一些研究和testing之后,我发现使用getText()。clear()清除文本的方式与setText(“”)非常相似,但是由于不设置文本,所以不会调用监听器解决了我的问题。 我将所有的setText(“”)调用切换到getText()。clear(),我不再需要绷带了,所以也许这也能解决你的问题。
尝试这个:
Field1 = (EditText)findViewById(R.id.field1); Field2 = (EditText)findViewById(R.id.field2); Field1.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { Field2.getText().clear(); } }); Field2.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { Field1.getText().clear(); } });
检查string之前设置另一个EditText
为空。 如果Field1
为空,那么为什么需要再次更改为(“”)? 所以你可以用s.lenght()或其他解决scheme检查你的string的大小
另一种可以检查string长度的方法是:
String sUsername = Field1.getText().toString(); if (!sUsername.matches("")) { // do your job }
我也面临同样的问题,并继续得到堆满的例外,我来与以下解决scheme。
edt_amnt_sent.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { if (skipOnChange) return; skipOnChange = true; try { //method } } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { skipOnChange = false; } } }); edt_amnt_receive.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { if (skipOnChange) return; skipOnChange = true; try { //method } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { skipOnChange = false; } } });
最初声明布尔值skipOnChange = false;
你也可以使用hasFocus()方法:
public void onTextChanged(CharSequence s, int start, int before, int count) { if (Field2.hasfocus()){ Field1.setText(""); } }
testing了这个大学作业,我正在努力将温度转换成用户input的温度。工作完美,而且更简单。
答案有点迟,但这是一个可重复使用的解决scheme:
/** * An extension of TextWatcher which stops further callbacks being called as * a result of a change happening within the callbacks themselves. */ public abstract class EditableTextWatcher implements TextWatcher { private boolean editing; @Override public final void beforeTextChanged(CharSequence s, int start, int count, int after) { if (editing) return; editing = true; try { beforeTextChange(s, start, count, after); } finally { editing = false; } } protected abstract void beforeTextChange(CharSequence s, int start, int count, int after); @Override public final void onTextChanged(CharSequence s, int start, int before, int count) { if (editing) return; editing = true; try { onTextChange(s, start, before, count); } finally { editing = false; } } protected abstract void onTextChange(CharSequence s, int start, int before, int count); @Override public final void afterTextChanged(Editable s) { if (editing) return; editing = true; try { afterTextChange(s); } finally { editing = false; } } public boolean isEditing() { return editing; } protected abstract void afterTextChange(Editable s); }
所以当使用上面的代码时,在TextWatcher中发生的任何setText()
调用都不会导致TextWatcher被再次调用:
/** * A setText() call in any of the callbacks below will not result in TextWatcher being * called again. */ public class MyTextWatcher extends EditableTextWatcher { @Override protected void beforeTextChange(CharSequence s, int start, int count, int after) { } @Override protected void onTextChange(CharSequence s, int start, int before, int count) { } @Override protected void afterTextChange(Editable s) { } }