如何更改DataChange上的TextView文本而不调用TextWatcher监听器

TextView textView=new TextView(context); textView.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { s.append("A"); } }); 

如果我们添加一个TextWatcher到一个TextView ,并且我想追加一个字母到这个TextView ,每次用户在其中写入一个字母,但是这个不停地重新调用TextWatcher Listener,所以就发生了StackOverFlow error ,所以如何附加一个文本而不用重新调用TextWatcher Listener?

Solutions Collecting From Web of "如何更改DataChange上的TextView文本而不调用TextWatcher监听器"

afterTextChanged的文档说:

这个方法被调用来通知你,在s中的某个地方,文本已经被改变了。 从这个callback中对s进行进一步的修改是合理的, 但是要注意不要让自己陷入无限循环,因为你所做的任何修改都会导致这个方法被recursion调用 (你没有被告知发生了什么变化,因为其他的afterTextChanged()方法可能已经做了其他的更改并且使得偏移无效。但是如果你需要知道这里,你可以在setSpan(Object, int, int, int)中使用setSpan(Object, int, int, int) onTextChanged(CharSequence, int, int, int)来标记你的位置,然后从这里查找跨度结束的位置。

所以,再次call afterTextChanged()等等每一个s.append("A")

这很容易:

 @Override public void afterTextChanged(Editable s) { editText.removeTextChangedListener(this); //Any modifications at this point will not be detected by TextWatcher, //so no more StackOverflowError s.append("A"); editText.addTextChangedListener(this); } 

另一种避免叠加的方法是:

 TextView textView=new TextView(context); textView.addTextChangedListener(new TextWatcher() { boolean editing=false; @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count,int after) { } @Override public void afterTextChanged(Editable s) { if (!editing){ editing=true; s.append("A"); editing=false; } } }); 

Kotlin版本

 editText.addTextChangedListener(object: TextWatcher { override fun afterTextChanged(s: Editable?) { if (s.toString().isNotBlank()) { val formattedValue: String = // Do some formatting editText.removeTextChangedListener(this) editText.setText(formattedValue) editText.setSelection(editText.text.toString().length) editText.addTextChangedListener(this) } } override fun beforeTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { } })