edittext
在Android开发中,格式化输入框输入的手机号码是一个很常用的事情,比如输入13333333333,最终需要格式化成为133 3333 3333格式。这是一个很常见的需求,但是实现起来还是有点麻烦,主要体现在以下几个地方:
这里先介绍一下一个很重要的接口,textwatcher
TextWatcher里面有三个方法:
beforeTextChanged(Charsequence s, int start, int count, int after)
onTextChanged(CharSequence s, int start, int before, int count)
afterTextChanged(Editable s)
这里有几个比较抽象的参数:beforeTextChanged的几个参数的意义分别是:
- CharSequence s: 变动之前的输入框中的内容
- int start: 发生变动的起始位置
- int count: 发生变动的时候影响到原字符串的个数(在插入的时候一般是0,删除的时候一般不为0)
- int after: 和上面的count相关,意思是上面count个字符串变成了after个字符串
这个会比较抽象,我们可以在代码中打印一下:
et.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Log.i("edittext", "beforeTextChanged CharSequence:(" + s + "); start: (" + start + "); count: (" + count + "); after: (" + after + ")");
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.i("edittext", "onTextChanged CharSequence:(" + s + "); start: (" + start + "); before: (" + before + "); count: (" + count + ")");
}
@Override
public void afterTextChanged(Editable s) {
Log.i("edittext", "分割线---------------------------------------------------------------------------------------------\n");
}
});
我们看下打印下来的日志:
我们在第七个字符的位置输入了3个m,所以应该是有三个流程打印出来的。
- 第一个日志 start = 6, count = 0, after = 1;我们输入的位置是第七个字符的位置,所以下标应该是6,在下标为6的地方往后0个字符被修改为了1个字符。我们是输入了一个字符,所以没有字符被修改,count = 0没毛病,然后新增了一个字符m,所以after = 1,也没毛病。
- 第二三个日志也是一样的,由于输入了字符,所以start的位置因该向前加一位,其他都一样。
我们可以再看下批量删除的日志,验证一下我们的结论:
日志:
我们删除了中间的三个mmm,看下日志,start = 6, count = 3, after = 0;从第六个字符开始后的3个字符被替换成了0个字符,所以是删除了三个字符,验证了我们的结论。
大家有兴趣可以自己再去验证一下粘贴复制这种情况,这里不再做论证。
简单介绍了下这几个参数的意义,下面我们分析一下上面说到的需求,格式化手机号:
当我们输入手机号的时候需要自动添加空格,而当我们删除手机号的时候也需要自动删除空格,我们可以根据beforeTextChanged()的参数方法判断出来当前是出于新增还是删除的情况:
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (s.length() == count && start == 0 && count != 0) {
inputMode = MODE_SET_TEXT;
} else if (after == 0) {
inputMode = MODE_DELETE;
curIndex = start;
if ((curIndex == 4 && s.length() >= 4) || (curIndex == 9 && s.length() >= 9)){
curIndex -= 1;
}
} else {
inputMode = MODE_INSERT;
curIndex = after + start;
if ((curIndex == 4 && s.length() >= 4) || (curIndex == 9 && s.length() >= 9)){
curIndex += 1;
}
}
}
这里需要注意,除了新增和删除,还有可能调用到setText()这个方法,当我们手动修改完text的时候需要通过setText()设置进去,这个时候需要一些特殊处理(当然也可以通过修改Editable参数修改)。curIndex参数用来记录当前光标所在的位置,这样可以使用户进行输入和删除包括复制粘贴的时候让光标停留在自己想要的位置,毕竟提高用户体验是我们的必要操作。
具体的代码贴在下面,大家感兴趣可以看看:
public class PhoneNumberTextWatcher implements TextWatcher {
private static final int MODE_INSERT = 0;
private static final int MODE_DELETE = 1;
private static final int MODE_SET_TEXT = 2;
/**
* 当前的输入模式,默认
*/
private int inputMode;
/**
* 当前的光标所在位置
*/
private int curIndex;
/**
* 输入手机号码的editText
*/
private EditText etPhone;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (s.length() == count && start == 0 && count != 0) {
inputMode = MODE_SET_TEXT;
if (curIndex == 4 && after > 4 || (curIndex == 9 && after > 9)){
curIndex += 1;
}
} else if (after == 0) {
inputMode = MODE_DELETE;
curIndex = start;
if ((curIndex == 4 && s.length() >= 4) || (curIndex == 9 && s.length() >= 9)){
curIndex -= 1;
}
} else {
inputMode = MODE_INSERT;
curIndex = after + start;
if ((curIndex == 4 && s.length() >= 4) || (curIndex == 9 && s.length() >= 9)){
curIndex += 1;
}
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String curString = s.toString();
String realString = curString.replace(" ", "");
int length = realString.length();
stringbuilder sb = new StringBuilder();
if (inputMode == MODE_INSERT) {
if (length < 3) {
return;
}
sb.append(realString.substring(0, 3));
sb.append(" ");
if (length < 7) {
sb.append(realString.substring(3, length));
} else {
sb.append(realString.substring(3, 7));
sb.append(" ");
sb.append(realString.substring(7, length));
}
} else if (inputMode == MODE_DELETE) {
if (length <= 3) {
sb.append(realString);
} else if (length <= 7) {
sb.append(realString.substring(0, 3));
sb.append(" ");
sb.append(realString.substring(3, length));
} else {
sb.append(realString.substring(0, 3));
sb.append(" ");
sb.append(realString.substring(3, 7));
sb.append(" ");
sb.append(realString.substring(7, length));
}
}
if (sb.length() != 0 && !sb.toString().equals(curString)) {
if (etPhone != null) {
etPhone.setText(sb);
}
}
if (length != 0 && etPhone != null) {
etPhone.setSelection(curIndex);
}
}
public void setEditText(EditText etPhone){
this.etPhone = etPhone;
this.etPhone.addTextChangedListener(this);
}
}
我们看下最终的效果:
使用方式:
EditText et = findViewById(R.id.et);
new PhoneNumberTextWatcher().setEditText(et);
对于银行卡号或者身份证的格式化同理也是这种思路。
相关阅读
1.打开系统设置: 2.Language Support:按照1,2,3,最后apply! 3.输入密码,自动下载安装包和安装 4.安装IBUS框架: sudo apt-get instal
同样是最常见的数字键盘,为什么我们在手机上使用的数字键盘和计算器上的顺序截然不同呢?电话的数字键盘和计算器的数字键盘摆在一起
免费的工具应用并不必然局限于产品周期里,当它的功能服务和内容挂钩,当这种内容能够衍生出社交网络的可能性,这种工具便有可能实现一
/* * 任意输入三角形三条整型边长 判断三角形的类型(普通 等腰 等边 直三角) */ #include <stdio.h> int main(void) { in
excel作为功能强大的办公软件,是非常重要的。许多朋友在输入身份证号的时候,会遇到类似3.62202E+17的情况,苦恼不堪。如何迅速的在ex