TextWatcher是一个用来监听文本变化的接口,使用该接口可以很方便的对可显示文本控件和可编辑文本控件中的文字进行监听和修改
TextWatcher接口中定义了三个方法:
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
该方法在文本改变之前调用,传入了四个参数:
- CharSequence s:文本改变之前的内容
- int start:文本开始改变时的起点位置,从0开始计算
- int count:要被改变的文本字数,即将要被替代的选中文本字数
- int after:改变后添加的文本字数,即替代选中文本后的文本字数
该方法调用是在文本没有被改变,但将要被改变的时候调用,把四个参数组成一句话就是:
在当前文本s中,从start位置开始之后的count个字符(即将)要被after个字符替换掉
public void onTextChanged(CharSequence s, int start, int before, int count) {}
该方法是在当文本改变时被调用,同样传入了四个参数:
- CharSequence s:文本改变之后的内容
- int start:文本开始改变时的起点位置,从0开始计算
- int before:要被改变的文本字数,即已经被替代的选中文本字数
- int count:改变后添加的文本字数,即替代选中文本后的文本字数
该方法调用是在文本被改变时,改变的结果已经可以显示时调用,把四个参数组成一句话就是:
在当前文本s中,从start位置开始之后的before个字符(已经)被count个字符替换掉了
public void afterTextChanged(Editable s) {}
该方法是在文本改变结束后调用,传入了一个参数:
- Editable s:改变后的最终文本
该方法是在执行完beforeTextChanged、onTextChanged两个方法后才会被调用,此时的文本s为最终显示给用户看到的文本。我们可以再对该文本进行下一步处理,比如把文本s显示在UI界面上
实践
使用TextWatcher监听EditText剩余可输入文本字数
有个这样的需求:用户在EditText中只能输入50个字符,在用户输入的同时在UI界面中告诉用户还可输入多少个字符
布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="vertical">
<!-- 文字输入框 -->
<EditText
android:id="@+id/edt_text_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/bg_edit_radius"
android:gravity="top"
android:maxLength="50"
android:minLines="5"
android:padding="10dp"
android:textColor="@android:color/white"
android:textSize="20sp"
/>
<!-- 已输入字数 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="已输入字数:"
android:textSize="16sp"/>
<TextView
android:id="@+id/tv_text_now_sum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="#ff0000"
android:textSize="16sp"/>
</LinearLayout>
<!-- 剩余可输入 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="剩余可输入:"
android:textSize="16sp"/>
<TextView
android:id="@+id/tv_text_remain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="50"
android:textColor="#ff0000"
android:textSize="16sp"/>
</LinearLayout>
</LinearLayout>
在以上布局中,EditText控件使用maxLength=”50”限制可输入字符为50个
需要使用的控件和变量
/** 输入框 */
private EditText mTextContentEdt;
/** 剩余字数 */
private TextView mTextRemainTv;
/** 已输入字数 */
private TextView mTextNowSumTv;
/** 总可输入字数 */
private int textRemainAll = 50;
输入框样式图片bg_edit_radius.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="1dp"
android:color="@android:color/black" />
<corners android:radius="10dp" />
<solid android:color="@android:color/darker_gray" />
</shape>
初始化界面
/**
* 初始化界面
*/
private void initUI() {
setContentView(R.layout.activity_main);
mTextContentEdt = (EditText) findViewById(R.id.edt_text_content);
mTextRemainTv = (TextView) findViewById(R.id.tv_text_remain);
mTextNowSumTv = (TextView) findViewById(R.id.tv_text_now_sum);
}
给EditText添加监听,MyTextWatcher类为我们自定义的监听类
/**
* 初始化监听
*/
private void initListener() {
mTextContentEdt.addTextChangedListener(new MyTextWatcher());
}
创建一个自定义的TextWatcher监听类,实现TextWatcher接口
/**
* 创建自己的TextWatcher监听类
*/
private class MyTextWatcher implements 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) {
// 已经输入的字数
mTextNowSumTv.setText(String.valueOf(s.length()));
// 剩余可输入字数
int remainSum = textRemainAll - s.length();
mTextRemainTv.setText(String.valueOf(remainSum));
}
@Override
public void afterTextChanged(Editable s) {
}
}
运行后的效果图