5

在我的 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)
        {               
        }
    });

我的程序终止了,即使我尝试在我的代码中捕获异常,它仍然终止。有谁知道为什么会发生这种情况以及我如何做到这一点?谢谢。

4

4 回答 4

11

的内容在事件中TextView不可编辑的。onTextChanged

相反,您需要处理afterTextChanged事件才能对文本进行更改。

有关更详尽的解释,请参阅: Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged


注意:错误onTextChanged

Obvioulsy,您通过不断更改事件上的文本来导致无限循环afterTextChanged

参考

public abstract void afterTextChanged (Editable s)
调用此方法是为了通知您,在 s 中的某处,文本已更改。从这个回调中对 s 进行进一步的更改是合法的,但请注意不要让自己陷入无限循环,因为您所做的任何更改都会导致再次递归调用此方法。...

  • 建议1:如果可以,请检查触发事件时s是否已经是您想要的。

    @Override
    public void afterTextChanged(Editable s)
    {    
        if( !s.equalsIngoreCase("smth defined previously"))
             s = "smth defined previously";              
    }
    
  • 建议 2:如果您需要做更复杂的事情(格式化、验证),您可以使用本文synchronized中的方法

注意 2:将输入格式化为部分隐藏,直到最后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
    }
于 2012-02-29T11:25:10.343 回答
2

迟到的答案,如果有人看这就是我的做法。

  • 最初设置 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) {


        }
    });
于 2017-04-12T17:17:25.363 回答
1

为了补充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 进行进一步更改是合法的,但请注意不要让自己陷入无限循环,因为您所做的任何更改都会导致再次递归调用此方法。

于 2016-08-02T12:40:30.140 回答
0

这是一个对我有用的片段

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

于 2018-02-27T09:15:20.070 回答