实现思路:为EditText设置监听,调用
addTextChangedListener(TextWatcher watcher)
方法。然后在onTextChanged()
方法中处理字符串并显示到EditText上,最后我们要在afterTextChanged(Editable s)
方法中将光标移动到最后
下面先熟悉一下TextWatcher 接口回调函数:
public interface TextWatcher extends NoCopySpan {
/**
* 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.
* 在字符串s内,从索引为start(包含)的字符开始的count个字符将被长度为after的新文
* 本代替
*/
public void beforeTextChanged(CharSequence s, int start,
int count, int after);
/**
* 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.
* 在字符串s内,从索引为start(包含)的字符开始count个字符刚刚替换了长度为before的
* 旧字符
*/
public void onTextChanged(CharSequence s, int start, int before, int 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.
* 字符串s内容已经发生了变化.可以在这一步对s进行合理的变更,但是要注意不要进入
* 无限循环,因为字符串的任何变化都会再次递归调用此回调方法.在这个方法中不会告
* 诉 你字符串哪些内容发生了变化,因为其他针对字符串的改变已经调用了
* afterTextChanged().如果你想知道哪些发生了变化,可以在
* onTextChanged(CharSequence, int, int, int)使用setSpan(Object, int, int, int)做标记
*/
public void afterTextChanged(Editable s);
}
实现代码如下:
注意,手机号码为11位,但是因为有特殊字符(代码中将空格替换为想要的字符)或者空格,所以EditText的
android:maxLength="13"
属性要设置为大于11,我的由于存在两个空格,所以设置最大为13。
<EditText
android:id="@+id/et_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:digits="1234567890"<!--只允许输入这10个数字-->
android:hint="请输入手机号"
android:inputType="phone|number"<!--设置键盘输入类型为数字键盘-->
android:maxLength="13" />
etPhone.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) {
int length = s.toString().length();
//删除数字
if (count == 0) {
if (length == 4) {
etPhone.setText(s.subSequence(0, 3));
}
if (length == 9) {
etPhone.setText(s.subSequence(0, 8));
}
}
//添加数字
if (count == 1) {
if (length == 4) {
String part1 = s.subSequence(0, 3).toString();
String part2 = s.subSequence(3, length).toString();
etPhone.setText(part1 + " " + part2);
}
if (length==9){
String part1 = s.subSequence(0, 8).toString();
String part2 = s.subSequence(8, length).toString();
etPhone.setText(part1 + " " + part2);
}
}
}
@Override
public void afterTextChanged(Editable s) {
//将光标移动到末尾
etPhone.setSelection(etPhone.getText().toString().length());
//处理s
});
代码很简单,下面看看效果图:
edit_text.png
虽然效果做出来了,但是当我们调用etPhone.getText().toString()
方法时,你会发现得到的结果里也是包含空格或者特殊字符的一串号码。如果想要纯数字的结果,那么就需要对结果进行一下处理:
//从EditText获取的字符串
String phoneNum=etPhone.getText().toString();
//纯数字字符串
String number=formatPhoneNum(phoneNum);
/**
* 去掉手机号内除数字外的所有字符
*
* @param phoneNum 手机号
* @return
*/
private String formatPhoneNum(String phoneNum) {
String regex = "(\\+86)|[^0-9]";
Pattern pattern = Pattern.compile(regex );
Matcher matcher = pattern.matcher(phoneNum);
return matcher.replaceAll("");
}