必威体育Betway必威体育官网
当前位置:首页 > IT技术

EditText格式化输入内容

时间:2019-08-31 06:10:00来源:IT技术作者:seo实验室小编阅读:68次「手机版」
 

edittext

Android开发中,格式化输入框输入的手机号码是一个很常用的事情,比如输入13333333333,最终需要格式化成为133 3333 3333格式。这是一个很常见的需求,但是实现起来还是有点麻烦,主要体现在以下几个地方:

  1. 在中间插入或者删除
  2. 复制粘贴的处理
  3. 标的处理。很多APP都是格式化完成后直接将光标定位到最后,或者直接强制关闭中间位置修改功能,或者关闭复制粘贴功能。

这里先介绍一下一个很重要的接口,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");
        }
    });

第一个

我们看下打印下来的日志:

日志1

我们在第七个字符的位置输入了3个m,所以应该是有三个流程打印出来的。

  • 第一个日志 start = 6, count = 0, after = 1;我们输入的位置是第七个字符的位置,所以下标应该是6,在下标为6的地方往后0个字符被修改为了1个字符。我们是输入了一个字符,所以没有字符被修改,count = 0没毛病,然后新增了一个字符m,所以after = 1,也没毛病。
  • 第二三个日志也是一样的,由于输入了字符,所以start的位置因该向前加一位,其他都一样。

我们可以再看下批量删除的日志,验证一下我们的结论:

第二个

日志:

日志2

我们删除了中间的三个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);

对于银行卡号或者身份证的格式化同理也是这种思路。

相关阅读

Ubuntu系统中添加中文输入法及其快捷键的设置

1.打开系统设置: 2.Language Support:按照1,2,3,最后apply! 3.输入密码,自动下载安装包和安装 4.安装IBUS框架: sudo apt-get instal

同样是输入数字,为何电话和计算器键盘布局截然相反?

同样是最常见的数字键盘,为什么我们在手机上使用的数字键盘和计算器上的顺序截然不同呢?电话的数字键盘和计算器的数字键盘摆在一起

作为一款免费产品的输入法,如何才能构造成熟可持续的商

免费的工具应用并不必然局限于产品周期里,当它的功能服务和内容挂钩,当这种内容能够衍生出社交网络的可能性,这种工具便有可能实现一

任意输入三角形三条整型边长 判断三角形的类型(普通

/* * 任意输入三角形三条整型边长 判断三角形的类型(普通 等腰 等边 直三角) */ #include <stdio.h> int main(void) { in

Excel2010中快速输入身份证号码的操作方法

excel作为功能强大的办公软件,是非常重要的。许多朋友在输入身份证号的时候,会遇到类似3.62202E+17的情况,苦恼不堪。如何迅速的在ex

分享到:

栏目导航

推荐阅读

热门阅读