How To Change TextView Text on DataChange Without Calling Back TextWatcher Listener

*爱你&永不变心* 提交于 2019-12-22 04:11:20

问题


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");

        }
    });

if we add a TextWatcher to a TextView, and i want to append an a letter to this TextView, every time the user write a letter in it, but this keeps re-call the TextWatcher Listener, so on to StackOverFlow error, so how to append an text without re-call the TextWatcher Listener?


回答1:


The documentation of afterTextChanged says:

This method is called to notify you that, somewhere within s, the text has been changed. It is legitimate to make further changes to s from this callback, but be careful not to get yourself into an infinite loop, because any changes you make will cause this method to be called again recursively. (You are not told where the change took place because other afterTextChanged() methods may already have made other changes and invalidated the offsets. But if you need to know here, you can use setSpan(Object, int, int, int) in onTextChanged(CharSequence, int, int, int) to mark your place and then look up from here where the span ended up.

So, with every s.append("A") you call afterTextChanged() again and so on.




回答2:


It's easy:

@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);
}



回答3:


Another way to avoid stackoverflow:

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;
        }


        }
    });



回答4:


Kotlin Version

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) {

    }

})


来源:https://stackoverflow.com/questions/6354833/how-to-change-textview-text-on-datachange-without-calling-back-textwatcher-liste

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!