美文网首页
TextWatcher避免出现StackOverflowErro

TextWatcher避免出现StackOverflowErro

作者: lxbnjupt | 来源:发表于2017-04-27 16:25 被阅读0次

    1.TextWatcher

    使用TextWatcher可以实现对EditText输入的监听,调用EditText的addTextChangedListener(TextWatcher watcher)方法即可。
    TextWatcher是一个接口类,所以必须实现TextWatcher里的3个方法:

    public interface TextWatcher extends NoCopySpan {
        public void beforeTextChanged(CharSequence s, int start, int count, int after);
        public void onTextChanged(CharSequence s, int start, int before, int count);
        public void afterTextChanged(Editable s);
    }
    

    2.监听器里的setText函数导致StackOverflowError错误

    private TextWatcher mTextWatcher = 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) {
                if (null == s || s.length() == 0) {
                    return;
                }
                String inputString = s.toString();
                String finalString = getFormatedInputString(inputString);
                if (!TextUtils.isEmpty(finalString)) {
                    mEditText.setText(finalString);
                    mEditText.setSelection(finalString.length());
                }
            }
    
            @Override
            public void afterTextChanged(Editable s) {
    
            }
        };
    

    假如按照上面所写的,一定会产生bug:Java.lang.StackOverflowError
    原因分析:在onTextChanged方法中,使用setText()方法,会重新触发监听器,并不断的进行递归,最后导致程序崩溃。

    3.解决方法

    (1)不要在监听器里写触发监听器的方法,特别是没有出口的方法相互调用。
    (2)可以写一个标志位:flag,假如EditText内容发生变化,才执行setText()方法,如果没有发生变化,就不执行监听器里的setText()方法

    private TextWatcher mTextWatcher = 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) {
                if (null == s || s.length() == 0) {
                    return;
                }
                //setText()会回调onTextChanged(),增加标志位防止出现堆栈溢出
                if (isChange) {
                    isChange = false;
                    return;
                }
                isChange = true;
                String inputString = s.toString();
                String finalString = getFormatedInputString(inputString);
                if (!TextUtils.isEmpty(finalString)) {
                    mEditText.setText(finalString);
                    mEditText.setSelection(finalString.length());
                }
            }
    
            @Override
            public void afterTextChanged(Editable s) {
    
            }
        };
    

    相关文章

      网友评论

          本文标题:TextWatcher避免出现StackOverflowErro

          本文链接:https://www.haomeiwen.com/subject/yxxnzttx.html