当我按下数字时如何使用EditText的onTextChanged事件?

51

我有一个带有"text = 0.00"EditText。当我按数字3时,它应该变成0.03,第二次按数字5时,文本应该是0.35。以及35.035.09等这样的文本。这些都使用同一个EditText来完成。

我应该如何实现这个功能?我尝试使用带有TextWatcher()addTextChangedListener()


你能给我你的解决方案吗?我需要完全相同的东西。 - M. Usman Khan
6个回答

104

你也可以尝试这个:

EditText searchTo = (EditText)findViewById(R.id.medittext);
searchTo.addTextChangedListener(new TextWatcher() {
    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        doSomething();
    } 
});

4
当我使用setText()时,onTextChanged方法会再次被调用,如何防止这种情况发生? - M. Usman Khan
5
在setText事件中,你无法阻止onTextChanged被调用。你需要自己处理,比如使用一些布尔变量,在设置文本之前将其设置为true,在onTextChanged中检查该布尔值,决定是否继续进行onTextChanged事件。另一个解决方法是在设置文本之前删除TextChangeListener,然后在设置文本后再将其设置回来。 - Khawar Raza
是的,你无法防止这种情况。如果您需要知道更改发生的位置,谷歌建议使用setSpan方法。 - Anatolii Shuba

40

您选择了正确的方法。您需要扩展 TextWatcher 类并重写 afterTextChanged()beforeTextChanged()onTextChanged() 方法。

您需要在 afterTextChanged() 方法中编写所需功能的逻辑以实现您要求的功能。


3
当我调用setText()时,会再次触发afterTextChanged,如何防止这种情况发生? - M. Usman Khan
1
虽然有点晚了,但是afterTextChanged的文档警告了这种情况,在此回调中对s进行进一步更改是合法的,但要小心不要陷入无限循环,因为您所做的任何更改都会导致该方法递归地再次被调用。所以不要从这里更改s,我想这就是解决方案? - JimLohse
有没有办法区分文本是由用户更改还是通过setText()方法更改的? - Donki

9

这里,我写了一些与您所需的类似的内容:

    inputBoxNumberEt.setText(".     ");
    inputBoxNumberEt.setSelection(inputBoxNumberEt.getText().length());
    inputBoxNumberEt.addTextChangedListener(new TextWatcher() {

        boolean ignoreChange = false;

        @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 (!ignoreChange) {
                String string = s.toString();
                string = string.replace(".", "");
                string = string.replace(" ", "");
                if (string.length() == 0)
                    string = ".     ";
                else if (string.length() == 1)
                    string = ".  " + string;
                else if (string.length() == 2)
                    string = "." + string;
                else if (string.length() > 2)
                    string = string.substring(0, string.length() - 2) + "." + string.substring(string.length() - 2, string.length());
                ignoreChange = true;
                inputBoxNumberEt.setText(string);
                inputBoxNumberEt.setSelection(inputBoxNumberEt.getText().length());
                ignoreChange = false;
            }
        }
    });

4
应该将逻辑放到“afterTextChanged”方法中。根据关于“onTextChanged”的文档,尝试从该回调函数对s进行更改是错误的。 - angryITguy
当用户按下返回按钮时,可能会出现一些问题。 - kartik srivastava

2

1
在 Kotlin Android 中,可以使用以下方式设置 EditText 的监听器:
   val searchTo : EditText = findViewById(R.id.searchTo)
   searchTo.addTextChangedListener(object : TextWatcher {
    override fun afterTextChanged(s: Editable) {

        // you can call or do what you want with your EditText here

        // yourEditText...
    }

    override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
    override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
})

0

这是可工作的 Kotlin 版本。

  yourEditText.addTextChangedListener(object: TextWatcher {
    override fun afterTextChanged(s: Editable?) {
      // TODO Auto-generated method stub
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
      // TODO Auto-generated method stub
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
      doSomething()
    }
  })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接