如何使用TextWatcher更新相同的EditText



在我的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()是返回格式化数字的方法

相关内容

  • 没有找到相关文章

最新更新