如何使用TextWatcher更新相同的EditText?

时间:2012-02-29 11:21:32

标签: java android android-edittext textwatcher android-textwatcher

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

我的程序终止,甚至我尝试捕获异常,就像在我的代码中它仍然终止。 有谁知道为什么会发生这种情况以及如何实现这一目标?感谢。

3 个答案:

答案 0 :(得分:10)

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

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

有关详细说明,请参阅:Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged


注意:错误onTextChanged

很明显,通过不断更改afterTextChanged事件中的文本,您将导致无限循环。

来自the ref

  

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

  • 建议1 :如果可以,请在触发事件时检查s 是否已经

    @Override
    public void afterTextChanged(Editable s)
    {    
        if( !s.equalsIngoreCase("smth defined previously"))
             s = "smth defined previously";              
    }
    
  • 建议2 :如果你需要做更复杂的事情(格式化, 验证)您可以使用this post.
  • 中的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
    }

答案 1 :(得分:1)

要补充Zortkun's answer(示例代码已完全破解),您可以使用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条件内进行更改 / strong>,如上所述。

正如afterTextChanged() javadocs所说:

  

从此回调中对s进行进一步更改是合法的,但是   小心不要陷入无限循环,因为任何   您所做的更改将导致再次调用此方法   递归。

答案 2 :(得分:1)

迟到的答案,如果有人看这个是我怎么做的。

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


        }
    });