详解EditText输入监听TextWatcher

一、前言:

日常开发中,我们可能会遇到需要监听EditText输入,比如判断输入是否为电话号码,获取输入的数据长度来限定字数等。这就需要监听EditText的输入状态。EditText使用TextWatcher实现类似按钮监听事件:

效果图:

image.png

二、代码展示:

1. MainActivity.java

public class MainActivity extends AppCompatActivity {
    private EditText mNumber;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mNumber = (EditText) findViewById(R.id.phone_number);
        //为EditText设置监听,注意监听类型为TextWatcher
        mNumber.addTextChangedListener(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) {
                toast("您输入的数据为:"+s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }

    private void toast(String s){
        Toast.makeText(getApplication(),s,Toast.LENGTH_SHORT).show();
    }
}

2. Activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:padding="10dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.alphathink.myapplication.MainActivity">

    <EditText
        android:id="@+id/phone_number"
        android:layout_width="368dp"
        android:layout_height="wrap_content"
        android:hint="@string/number"
        android:inputType="number"
        tools:layout_editor_absoluteY="0dp"
        tools:layout_editor_absoluteX="8dp" />

</LinearLayout>

三、TextWatcher详解

1. 注意:

CharSequence是一个接口,比较常见的String、StringBuilder、StringBuffer都实现了这个接口。当我们看到一个API里面有CharSequence的时候,它也是可以被其子类代替的,一般用String代替即可。

我们看到TextWatcher监听里覆写了3个方法:

void beforeTextChanged(CharSequence s, int start, int count, int after);
void onTextChanged(CharSequence s, int start, int before, int count);
void afterTextChanged(Editable s);

行顺序来说是:beforeTextChanged()>>>onTextChanged()>>>afterTextChanged()

请勿在afterTextChanged();内加入代码进行验证,这个会进入死循环的,后边讲原因。

2. 关于beforeTextChanged(CharSequence s, int start, int count, int after);

官方文档解释:

void beforeTextChanged (CharSequence s, 
                int start, 
                int count, 
                int after)

This method is called to notify you that, within s, the count characters beginning at start are about to be replaced by new text with length after. It is an error to attempt to make changes to s from this callback. 

意思大概是:
这个方法用来通知你,在字符串s里,光标start开始处的count个字符将要被after长的字符代替,禁止在这个回调里改字符串s。可以理解成提醒你你做了什么操作。
操作》》》系统提醒你做了什么事(还没做)》》》》系统开始做
@Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                toast("s字符串为:"+s+"开始处:"+start+",替换体的长度:"+count+"后替换体长度"+after);
            }

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

            }

     @Override
     public void afterTextChanged(Editable s) {

     }

分别输入一个字符、二个字符、删除一个字符的截图


image.png
image.png
image.png

这样理解:

这个方法执行获取的状态是在你输入前光标所在位置:
输入一个字符:s字符串也就是当前EditText中的内容为空,所以输出空;
              开始处:0,司空见惯,从0计数;
              替换长度:0,这个怎么理解呢?理解成将被替换长度即可,你要在光标处往后替换然而往后并没有
              字符;
              后替换体长度:1,虽然他光标没动,这里表示他将要改变的长度,等于你输入字符长度1。

输入二个字符:s字符串是什么?我们刚刚输入的你字是不是还在,这就是s的内容;
            开始处:光标所在位置1;
            替换长度:0,为什么还是0?实话说这个是一直为0的,因为在你输入前执行,你所做的操作时
            一直往后增加,而增加操作相当于用输入字符替换了一个长度为0的字符,也就是空,所以一直为0;
            后替换体长度:等于替换字符长度。

删除一个字符:删除前执行,所以内容为“你你好”;
            开始处:2,光标所在位;
            替换体长度:1,这个这里就变了,为什么变了呢?因为我们做了删除操作,被替换的长度是删除的
            那个字符长度也就是1;
            后替换体的长度:0,这个又是一直为0的,为什么呢,和前边那个一直为0的原因一样,我们做删除操作
            等于用空来替换一个字符,所以替换的长度为空的长度,也就是0;

这个原理理解了的话,对于void onTextChanged(CharSequence s, int start, int before, int count); 和这个类似,官方文档如下:

void onTextChanged (CharSequence s, 
                int start, 
                int before, 
                int count)

This method is called to notify you that, within s, the count characters beginning at start have just replaced old text that had length before. It is an error to attempt to make changes to s from this callback. 

意思大概是:这个方法是用来告诉你,在字符串s里,光标start开始处的count个字符刚刚把原来的before长度的字符替换。理解为通知你刚刚做,或正在做,主要与后边afterTextChanged()方法区分;

代码更改如下:

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    toast("s字符串为:"+s+",开始处:"+start+",替换体长度:"+count+",前替换体长度"+before);
}

@Override
public void afterTextChanged(Editable s) {

}

分别输入一个字符、二个字符、删除一个字符的截图:


image.png
image.png
image.png

结合第一个理解:这个方法在你刚刚操作后提示你:

输入一个字符:s替换后后执行此方法,所以可以读取到字符串“你”;
        开始处0:下标位,接下来不说了这个。
        替换体:也就是你输入的字符长度,“你”的长度为1;
        前替换体:0,你用“你”这个字符替换了长度为0
                                        的字符。
输入二个字符:替换体为你输入的“你好”的长度2;
         前替换体:0,同上。
删除一个字符:s字符为“你你”;
         替换体长度:0,好比你用长度为0的字符代替了“你”字;
         前替换体:1,“你”的长度。

对于 void afterTextChanged(Editable s):

官方解释:

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.

意思是:这个方法告诉你,在字符串s内的某处,一些地方已经改变了,在这个方法里可以对s做一些改变,但是注意别让你陷入反复调用它的问题上,因为可能你做的任何改变会让他递归调用本身。(这个方法没有告诉你哪里改变了,或许其他afterTextChanged()可能已经改变它了并使这个改变失效,但是如果你确定知道他是否起作用了,你可以在onTextChanged()里调用setSpan(Object, int, int, int)方法去标记并在此验证是否在这结束了))

来吧我们来验证一下这个方法做了什么事:

修改代码:

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

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

}

@Override
public void afterTextChanged(Editable s) {
        s.append("hello");
       toast(s.toString());
}

假如我们输入“你”字,预测结果是不是:

你hello

然而结果是:

.......竟然ANR了。也就是程序无响应了 -_-!

修改EditText的输入长度为15再试试:

android:maxLength="15"

运行截图:

image.png

详解EditText输入监听TextWatcher

2017年03月18日 18:18:35鼎鼎浩阅读数 16291文章标签:EditText监听 android TextWatche 更多

分类专栏:Android基础

<article class="baidu_pl" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: -webkit-standard; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;">

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/Z_DingHao/article/details/63263129


日常开发中,我们可能会遇到需要监听EditText输入,比如判断输入是否为电话号码,获取输入的数据长度来限定字数等。这就需要监听EditText的输入状态。EditText使用TextWatcher实现类似按钮监听事件:

使用方法
效果图:

这里写图片描述

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private EditText mNumber;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mNumber = (EditText) findViewById(R.id.phone_number);
        //为EditText设置监听,注意监听类型为TextWatcher
        mNumber.addTextChangedListener(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) {
                toast("您输入的数据为:"+s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }

    private void toast(String s){
        Toast.makeText(getApplication(),s,Toast.LENGTH_SHORT).show();
    }
}

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:padding="10dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.alphathink.myapplication.MainActivity">

    <EditText
        android:id="@+id/phone_number"
        android:layout_width="368dp"
        android:layout_height="wrap_content"
        android:hint="@string/number"
        android:inputType="number"
        tools:layout_editor_absoluteY="0dp"
        tools:layout_editor_absoluteX="8dp" />

</LinearLayout>


TextWatcher详解

注意:
CharSequence是一个接口,比较常见的String、StringBuilder、StringBuffer都实现了这个接口。当我们看到一个API里面有CharSequence的时候,它也是可以被其子类代替的,一般用String代替即可。

我们看到TextWatcher监听里覆写了3个方法:

     void beforeTextChanged(CharSequence s, int start, int count, int after);   
     void onTextChanged(CharSequence s, int start, int before, int count);  
     void afterTextChanged(Editable s); 

执行顺序来说是:beforeTextChanged()>>>onTextChanged()>>>afterTextChanged()

请勿在afterTextChanged();内加入代码进行验证,这个会进入死循环的,后边讲原因。


关于beforeTextChanged(CharSequence s, int start, int count, int after);

官方文档解释:

void beforeTextChanged (CharSequence s, 
                int start, 
                int count, 
                int after)

This method is called to notify you that, within s, the count characters beginning at start are about to be replaced by new text with length after. It is an error to attempt to make changes to s from this callback. 

意思大概是:
这个方法用来通知你,在字符串s里,光标start开始处的count个字符将要被after长的字符代替,禁止在这个回调里改字符串s。可以理解成提醒你你做了什么操作。
操作》》》系统提醒你做了什么事(还没做)》》》》系统开始做
@Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                toast("s字符串为:"+s+"开始处:"+start+",替换体的长度:"+count+"后替换体长度"+after);
            }

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

            }

     @Override
     public void afterTextChanged(Editable s) {

            }

分别输入一个字符、二个字符、删除一个字符的截图

这里写图片描述
这里写图片描述
这里写图片描述

这样理解:

这个方法执行获取的状态是在你输入前光标所在位置:
输入一个字符:s字符串也就是当前EditText中的内容为空,所以输出空;
              开始处:0,司空见惯,从0计数;
              替换长度:0,这个怎么理解呢?理解成将被替换长度即可,你要在光标处往后替换然而往后并没有
              字符;
              后替换体长度:1,虽然他光标没动,这里表示他将要改变的长度,等于你输入字符长度1。

输入二个字符:s字符串是什么?我们刚刚输入的你字是不是还在,这就是s的内容;
            开始处:光标所在位置1;
            替换长度:0,为什么还是0?实话说这个是一直为0的,因为在你输入前执行,你所做的操作时
            一直往后增加,而增加操作相当于用输入字符替换了一个长度为0的字符,也就是空,所以一直为0;
            后替换体长度:等于替换字符长度。

删除一个字符:删除前执行,所以内容为“你你好”;
            开始处:2,光标所在位;
            替换体长度:1,这个这里就变了,为什么变了呢?因为我们做了删除操作,被替换的长度是删除的
            那个字符长度也就是1;
            后替换体的长度:0,这个又是一直为0的,为什么呢,和前边那个一直为0的原因一样,我们做删除操作
            等于用空来替换一个字符,所以替换的长度为空的长度,也就是0;

这个原理理解了的话,对于void onTextChanged(CharSequence s, int start, int before, int count); 和这个类似,官方文档如下:

void onTextChanged (CharSequence s, 
                int start, 
                int before, 
                int count)

This method is called to notify you that, within s, the count characters beginning at start have just replaced old text that had length before. It is an error to attempt to make changes to s from this callback. 

意思大概是:这个方法是用来告诉你,在字符串s里,光标start开始处的count个字符刚刚把原来的before长度的字符替换。理解为通知你刚刚做,或正在做,主要与后边afterTextChanged()方法区分;

代码更改如下:

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    toast("s字符串为:"+s+",开始处:"+start+",替换体长度:"+count+",前替换体长度"+before);
}

@Override
public void afterTextChanged(Editable s) {

}

分别输入一个字符、二个字符、删除一个字符的截图:

这里写图片描述
这里写图片描述
这里写图片描述

结合第一个理解:这个方法在你刚刚操作后提示你:

输入一个字符:s替换后后执行此方法,所以可以读取到字符串“你”;
                        开始处0:下标位,接下来不说了这个。
                        替换体:也就是你输入的字符长度,“你”的长度为1;
                        前替换体:0,你用“你”这个字符替换了长度为0
                                        的字符。
输入二个字符:替换体为你输入的“你好”的长度2;
                        前替换体:0,同上。
删除一个字符:s字符为“你你”;
                        替换体长度:0,好比你用长度为0的字符代替了“你”字;
                        前替换体:1,“你”的长度。

对于 void afterTextChanged(Editable s):

官方解释:

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.

意思是:这个方法告诉你,在字符串s内的某处,一些地方已经改变了,在这个方法里可以对s做一些改变,但是注意别让你陷入反复调用它的问题上,因为可能你做的任何改变会让他递归调用本身。(这个方法没有告诉你哪里改变了,或许其他afterTextChanged()可能已经改变它了并使这个改变失效,但是如果你确定知道他是否起作用了,你可以在onTextChanged()里调用setSpan(Object, int, int, int)方法去标记并在此验证是否在这结束了))

来吧我们来验证一下这个方法做了什么事:

修改代码:

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

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

            }

            @Override
            public void afterTextChanged(Editable s) {
                s.append("hello");
                toast(s.toString());
            }

假如我们输入“你”字,预测结果是不是:

你hello

然而结果是:

.......竟然ANR了。也就是程序无响应了 -_-!

修改EditText的输入长度为15再试试:

android:maxLength="15"

运行截图:


这里写图片描述

达到最大长度才显示了一下,我们可以推测到,他竟然递归调用了。。。所以文档中说到谨慎一点,小心陷入递归自身的问题。所以这个方法是在你输入完后才调用的,你输入一个字符,然后以后是不是一直处于输入完成状态,所以他一直在调用这个方法。

详解EditText输入监听TextWatcher

2017年03月18日 18:18:35鼎鼎浩阅读数 16291文章标签:EditText监听 android TextWatche 更多

分类专栏:Android基础

<article class="baidu_pl" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: -webkit-standard; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;">

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/Z_DingHao/article/details/63263129


日常开发中,我们可能会遇到需要监听EditText输入,比如判断输入是否为电话号码,获取输入的数据长度来限定字数等。这就需要监听EditText的输入状态。EditText使用TextWatcher实现类似按钮监听事件:

使用方法
效果图:

这里写图片描述

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private EditText mNumber;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mNumber = (EditText) findViewById(R.id.phone_number);
        //为EditText设置监听,注意监听类型为TextWatcher
        mNumber.addTextChangedListener(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) {
                toast("您输入的数据为:"+s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }

    private void toast(String s){
        Toast.makeText(getApplication(),s,Toast.LENGTH_SHORT).show();
    }
}

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:padding="10dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.alphathink.myapplication.MainActivity">

    <EditText
        android:id="@+id/phone_number"
        android:layout_width="368dp"
        android:layout_height="wrap_content"
        android:hint="@string/number"
        android:inputType="number"
        tools:layout_editor_absoluteY="0dp"
        tools:layout_editor_absoluteX="8dp" />

</LinearLayout>


TextWatcher详解

注意:
CharSequence是一个接口,比较常见的String、StringBuilder、StringBuffer都实现了这个接口。当我们看到一个API里面有CharSequence的时候,它也是可以被其子类代替的,一般用String代替即可。

我们看到TextWatcher监听里覆写了3个方法:

     void beforeTextChanged(CharSequence s, int start, int count, int after);   
     void onTextChanged(CharSequence s, int start, int before, int count);  
     void afterTextChanged(Editable s); 

执行顺序来说是:beforeTextChanged()>>>onTextChanged()>>>afterTextChanged()

请勿在afterTextChanged();内加入代码进行验证,这个会进入死循环的,后边讲原因。


关于beforeTextChanged(CharSequence s, int start, int count, int after);

官方文档解释:

void beforeTextChanged (CharSequence s, 
                int start, 
                int count, 
                int after)

This method is called to notify you that, within s, the count characters beginning at start are about to be replaced by new text with length after. It is an error to attempt to make changes to s from this callback. 

意思大概是:
这个方法用来通知你,在字符串s里,光标start开始处的count个字符将要被after长的字符代替,禁止在这个回调里改字符串s。可以理解成提醒你你做了什么操作。
操作》》》系统提醒你做了什么事(还没做)》》》》系统开始做
@Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                toast("s字符串为:"+s+"开始处:"+start+",替换体的长度:"+count+"后替换体长度"+after);
            }

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

            }

     @Override
     public void afterTextChanged(Editable s) {

            }

分别输入一个字符、二个字符、删除一个字符的截图

这里写图片描述
这里写图片描述
这里写图片描述

这样理解:

这个方法执行获取的状态是在你输入前光标所在位置:
输入一个字符:s字符串也就是当前EditText中的内容为空,所以输出空;
              开始处:0,司空见惯,从0计数;
              替换长度:0,这个怎么理解呢?理解成将被替换长度即可,你要在光标处往后替换然而往后并没有
              字符;
              后替换体长度:1,虽然他光标没动,这里表示他将要改变的长度,等于你输入字符长度1。

输入二个字符:s字符串是什么?我们刚刚输入的你字是不是还在,这就是s的内容;
            开始处:光标所在位置1;
            替换长度:0,为什么还是0?实话说这个是一直为0的,因为在你输入前执行,你所做的操作时
            一直往后增加,而增加操作相当于用输入字符替换了一个长度为0的字符,也就是空,所以一直为0;
            后替换体长度:等于替换字符长度。

删除一个字符:删除前执行,所以内容为“你你好”;
            开始处:2,光标所在位;
            替换体长度:1,这个这里就变了,为什么变了呢?因为我们做了删除操作,被替换的长度是删除的
            那个字符长度也就是1;
            后替换体的长度:0,这个又是一直为0的,为什么呢,和前边那个一直为0的原因一样,我们做删除操作
            等于用空来替换一个字符,所以替换的长度为空的长度,也就是0;

这个原理理解了的话,对于void onTextChanged(CharSequence s, int start, int before, int count); 和这个类似,官方文档如下:

void onTextChanged (CharSequence s, 
                int start, 
                int before, 
                int count)

This method is called to notify you that, within s, the count characters beginning at start have just replaced old text that had length before. It is an error to attempt to make changes to s from this callback. 

意思大概是:这个方法是用来告诉你,在字符串s里,光标start开始处的count个字符刚刚把原来的before长度的字符替换。理解为通知你刚刚做,或正在做,主要与后边afterTextChanged()方法区分;

代码更改如下:

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    toast("s字符串为:"+s+",开始处:"+start+",替换体长度:"+count+",前替换体长度"+before);
}

@Override
public void afterTextChanged(Editable s) {

}

分别输入一个字符、二个字符、删除一个字符的截图:

这里写图片描述
这里写图片描述
这里写图片描述

结合第一个理解:这个方法在你刚刚操作后提示你:

输入一个字符:s替换后后执行此方法,所以可以读取到字符串“你”;
                        开始处0:下标位,接下来不说了这个。
                        替换体:也就是你输入的字符长度,“你”的长度为1;
                        前替换体:0,你用“你”这个字符替换了长度为0
                                        的字符。
输入二个字符:替换体为你输入的“你好”的长度2;
                        前替换体:0,同上。
删除一个字符:s字符为“你你”;
                        替换体长度:0,好比你用长度为0的字符代替了“你”字;
                        前替换体:1,“你”的长度。

对于 void afterTextChanged(Editable s):

官方解释:

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.

意思是:这个方法告诉你,在字符串s内的某处,一些地方已经改变了,在这个方法里可以对s做一些改变,但是注意别让你陷入反复调用它的问题上,因为可能你做的任何改变会让他递归调用本身。(这个方法没有告诉你哪里改变了,或许其他afterTextChanged()可能已经改变它了并使这个改变失效,但是如果你确定知道他是否起作用了,你可以在onTextChanged()里调用setSpan(Object, int, int, int)方法去标记并在此验证是否在这结束了))

来吧我们来验证一下这个方法做了什么事:

修改代码:

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

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

            }

            @Override
            public void afterTextChanged(Editable s) {
                s.append("hello");
                toast(s.toString());
            }

假如我们输入“你”字,预测结果是不是:

你hello

然而结果是:

.......竟然ANR了。也就是程序无响应了 -_-!

修改EditText的输入长度为15再试试:

android:maxLength="15"

运行截图:


这里写图片描述

达到最大长度才显示了一下,我们可以推测到,他竟然递归调用了。。。所以文档中说到谨慎一点,小心陷入递归自身的问题。所以这个方法是在你输入完后才调用的,你输入一个字符,然后以后是不是一直处于输入完成状态,所以他一直在调用这个方法。

五、总结

一般我们在onTextChanged();方法里做一些自己要做的事,比如监听输入的字符长度,或者应用在验证输入一个手机号就设置按钮可点击等等。
beforeTextChanged();在View改变之前执行,好比你输入了字符,系统先统计你输入的信息,在这里可以提前获取你的动机。
onTextChanged();在View改变之后短时间内执行,也就是区别afterTextChanged();的一直执行状态,他只调用一次。我们做自己的操作一般在这里;
afterTextChanged();在你输入完成后执行,我们输入完后处于完成状态,他就监测到完成了就不断的执行,因为我们不操作,是不是一直处于完成状态?所以就处于死循环了。切记在此做操作。


参考链接:https://blog.csdn.net/z_dinghao/article/details/63263129

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,401评论 0 17
  • Listview输入框动态加载 在写一些项目中,需要提交大量的数据,有时候同级别的信息汇总时,针对不同类型所要上传...
    罗雪鹏阅读 422评论 0 0
  • 我们使用EditText控件的时候,可能会遇到这样一种情况,在输入的时候,要求禁止输入某些字符。如输入$,#等特殊...
    我啊翔1314阅读 4,719评论 0 15
  • 先上效果图吧,这个相对来说比较简单,但是真正实现的时候,之前实习的时候做过一个简陋的,有很多很多的瑕疵,现在得空了...
    黑白咖阅读 3,594评论 7 20
  • Android开发之EditText属性详解 1、EditText输入的文字为密码形式的设置 (1)通过.xml里...
    y_2dbc阅读 1,470评论 0 3