在我的Android应用程序中,我需要实现一个TextWatcher接口来实现onTextChanged
。我的问题是,我想用一些额外的字符串更新相同的EditText。当我尝试这样做时,程序终止。
final EditText ET = (EditText) findViewById(R.id.editText1);
ET.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
try
{
ET.setText("***"+ s.toString());
ET.setSelection(s.length());
}
catch(Exception e)
{
Log.v("State", e.getMessage());
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
@Override
public void afterTextChanged(Editable s)
{
}
});
我的程序终止了,即使我试图捕捉异常,就像在我的代码中一样,它仍然终止了。有人知道为什么会发生这种情况,以及我如何做到这一点吗?谢谢
TextView
的内容在onTextChanged
事件上是不可编辑的。
相反,您需要处理afterTextChanged
事件才能对文本进行更改。
有关更全面的解释,请参阅:Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged
注意:错误onTextChanged
很明显,您通过连续更改afterTextChanged
事件上的文本,导致了一个无休止的循环。
参考:
文本更改后的公共摘要无效(可编辑)
调用此方法是为了通知您,在s中的某个位置,文本已经已更改。在此基础上对s进行进一步更改是合法的回调,但要小心不要让自己陷入无限循环,因为您所做的任何更改都将导致再次调用此方法递归地
-
建议1:如果可以,请检查事件触发时
s
是否已经是您想要的。@Override public void afterTextChanged(Editable s) { if( !s.equalsIngoreCase("smth defined previously")) s = "smth defined previously"; }
-
建议2:如果你需要做更复杂的事情(格式化,验证),您可以使用
synchronized
方法,如下所示职位
注意2:用n星将输入格式化为部分隐藏,直到最后4个字符(***四个)
你可以在建议1中使用类似的东西:
@Override
public void afterTextChanged(Editable s)
{
String sText = ET.getText().toString()
if( !isFormatted(sText))
s = format(sText);
}
bool isFormatted(String s)
{
//check if s is already formatted
}
string format(String s)
{
//format s & return
}
为了补充Zortkun的答案(示例代码完全损坏),以下是使用afterTextChanged()
更新相同EditText
:的方法
editText.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 editable) {
if (!editable.toString().startsWith("***")) {
editable.insert(0, "***");
}
}
});
熟悉Editable
界面,了解除insert()
之外的其他操作。
请注意,很容易陷入无限循环(您所做的更改再次触发afterTextChanged()
),因此通常您会在if条件内执行更改,如上所述。
正如afterTextChanged()
javadocs所说:
通过此回调对s进行进一步更改是合法的,但是小心不要让自己陷入无限循环,因为任何您所做的更改将导致再次调用此方法递归地。
答案很晚,如果有人在看,我就是这么做的。
- 最初设置addTextChangedListener
- 在其中一个回调中(比如onTextChanged())移除addTextChangedListener
- 仍然有兴趣接收更新,请再次添加
这是代码。
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Log.d("log", "before");
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d("log", "after");
editText.removeTextChangedListener(this);
ediText.setText("text you wanted to put");
editText.addTextChangedListener(this);
}
@Override
public void afterTextChanged(Editable s) {
}
});
这是一个对我有用的片段
etPhoneNumber.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 (!s.toString().equals(Utils.getFormattedNumber(s.toString()))) {
s.replace(0, s.length(), Utils.getFormattedNumber(s.toString()));
}
}
});
其中Utils.getFormattedPhoneNumber()
是返回格式化数字的方法