TextWatcher,还有在其中setText会引起StackOverflowError,银行卡输入四位空一格

一.背景

最近老是用到TextWatcher,其中有些细节老忘记

二.例子

public class MainActivity extends Activity {
    private EditText et_one;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_one = (EditText) findViewById(R.id.et_text);
        et_one.addTextChangedListener(new MyTextWatcher());
    }

    private class MyTextWatcher implements TextWatcher{

//        * s 为变化前的内容;
//        * start 为开始变化位置的索引,从0开始计数;
//        * count 是从start开始为将要发生变化的字符数(开始什么都没有就是0)
//        * after 为用来替换旧文本的长度,比如s由1变为12,after为1,由12变为1,after为0;
        //  1.开始什么都没有,然后输入一个1,after是1
        //不能通过该函数改变s的内容
        /**  * This method is called to notify you that, within <code>s</code>,  * the <code>count</code> characters beginning at <code>start</code>  * are about to be replaced by new text with length <code>after</code>.  * It is an error to attempt to make changes to <code>s</code> from  * this callback.  */  @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            System.out.println("xcwbeforeTextChanged  "+"s  "+s+"  start--"+"  count--"+count+"  after--"+after);
        }

//        *  在s中,从start处开始的count个字符刚刚替换了原来长度为before的文本
//        *  s 为变化后的内容;
//        *  start 为开始变化位置的索引,从0开始计数;
//        *  before 为被取代的老文本的长度,比如s由1变为12,before为0,由12变为1,before为1;
//        *  count 从start开始已经被替换的老字符的长度
        //不能通过该函数改变s的内容
        /**  * This method is called to notify you that, within <code>s</code>,  * the <code>count</code> characters beginning at <code>start</code>  * have just replaced old text that had length <code>before</code>.  * It is an error to attempt to make changes to <code>s</code> from  * this callback.  */  @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            System.out.println("xcwonTextChanged  "+"s  "+s+"  start--"+"  before--"+before+"  count--"+count);
        }
        /**  * This method is called to notify you that, somewhere within  * <code>s</code>, the text has been changed.  * It is legitimate to make further changes to <code>s</code> 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 {@link Spannable#setSpan} in {@link #onTextChanged}  * to mark your place and then look up from here where the span  * ended up.  */  @Override
        public void afterTextChanged(Editable s) {
            System.out.println("xcwafterTextChanged  "+"s--"+s);
        }
    }


}


结果以及总结:

//无---》1
09-25 11:00:44.772  22966-22966/com.weixin.mytext I/System.out﹕ xcwbeforeTextChanged  s    start--  count--0  after--1
09-25 11:00:44.773  22966-22966/com.weixin.mytext I/System.out﹕ xcwonTextChanged  s  1  start--  before--0  count--1
09-25 11:00:44.778  22966-22966/com.weixin.mytext I/System.out﹕ xcwafterTextChanged  s--1

//1---》无
09-25 11:05:01.364  22966-22966/com.weixin.mytext I/System.out﹕ xcwbeforeTextChanged  s  1  start--  count--1  after--0
09-25 11:05:01.365  22966-22966/com.weixin.mytext I/System.out﹕ xcwonTextChanged  s    start--  before--1  count--0
09-25 11:05:01.373  22966-22966/com.weixin.mytext I/System.out﹕ xcwafterTextChanged  s--


//1--->12
09-25 11:08:13.547  22966-22966/com.weixin.mytext I/System.out﹕ xcwbeforeTextChanged  s  1  start--  count--0  after--1
09-25 11:08:13.548  22966-22966/com.weixin.mytext I/System.out﹕ xcwonTextChanged  s  12  start--  before--0  count--1
09-25 11:08:13.554  22966-22966/com.weixin.mytext I/System.out﹕ xcwafterTextChanged  s--12


//12----1
09-25 11:09:17.882  22966-22966/com.weixin.mytext I/System.out﹕ xcwbeforeTextChanged  s  12  start--  count--1  after--0
09-25 11:09:17.884  22966-22966/com.weixin.mytext I/System.out﹕ xcwonTextChanged  s  1  start--  before--1  count--0
09-25 11:09:17.892  22966-22966/com.weixin.mytext I/System.out﹕ xcwafterTextChanged  s--1




TextWatcher fieldValidatorTextWatcher = new TextWatcher() {
            @Override
            public void afterTextChanged(Editable s) {//表示最终内容
            Log.d("afterTextChanged", s.toString());
            }




            @Override
            public void beforeTextChanged(CharSequence s, int start/*开始的位置*/, int count/*被改变的旧内容数*/, int after/*改变后的内容数量*/) {
            //这里的s表示改变之前的内容,通常start和count组合,可以在s中读取本次改变字段中被改变的内容。而after表示改变后新的内容的数量。
            }




            @Override
            public void onTextChanged(CharSequence s, int start/*开始位置*/, int before/*改变前的内容数量*/, int count/*新增数*/) {
             //这里的s表示改变之后的内容,通常start和count组合,可以在s中读取本次改变字段中新的内容。而before表示被改变的内容的数量。
            }
        };


三.遇到的问题

public void afterTextChanged(Editable s) {       
            setText(“字符串”);
}

现象:

        结果出现  StackOverflowError

原因:

因为setText,本身就会触发TextWatcher,然后不断的调用setText(),结果是调用函数堆栈溢出,

解决方法:

在setText前后价格标记就行了

private  boolean  flag = false;
public void afterTextChanged(Editable s) {
    if(flag){
        return ;
    }
    flag = true;
    setText("字符串");
    flag = false;
}

这样就不会重复调用


四.银行卡输入四位空一格的自定义的EditText

asdasd




你可能感兴趣的:(TextWatcher,还有在其中setText会引起StackOverflowError,银行卡输入四位空一格)