手机号码、银行卡输入添加空格

一、前言

对于移动端开发来讲,这种需求是很常见的,需要对手机号、银行卡号添加空格或者横线便于用户阅读,总体来说还是很简单的一个需求,实现起来说简单也简单,但是没选择正确的方法也是稍微有点麻烦的。为什么这么说呢,前几天浏览博客看到一篇文章实现了输入手机号添加空格,不过只考虑了末尾输入这一种情况,网上搜索了一下,大多数也是没有考虑所有的情况,中间插入、删除,复制等,所以如果用最常规的对输入的字符串输入后进行格式化,那么就需要考虑的是光标的位置,需要一定的耐心调试,本文采用另一种相对简单的方式来实现。

二、实现

对于 EditText 实现添加空格,实现这个需求肯定是要调用 addTextChangedListener 这个接口,监听输入的变化情况。最开始我是使用对输入后的字符串进行格式化,但是就是针对每种情况设置光标的位置比较麻烦,我也尝试了写出来了,不过就是处理复制任意长的字符串光标不好精确设置。我后面发现通过 Editable 来插入、删除等是不需要考虑光标的, 关于 EditTable 可以参照这篇文章 TextView源码解析 。那么实现就相对简单很多,话不多说看代码:

private static final char space = ' '; //也可以是'-'
private MyTextWatch myTextWatch;

myTextWatch = new MyTextWatch();
editText.addTextChangedListener(myTextWatch);

private class MyTextWatch 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) {
        }

        @Override
        public void afterTextChanged(Editable s) {
            format(s);
        }
    }
private void format(Editable s) {
        if (s.length() < 4) return;
        editText.removeTextChangedListener(myTextWatch);
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == space) {
                s.delete(i, i + 1);
            }
        }
        int length = s.length();
        if (length > 7) {
            s.insert(3, String.valueOf(space));
            if (editText.getSelectionStart() == 4) {
                editText.setSelection(3);
            }
            s.insert(8, String.valueOf(space));
            if (editText.getSelectionStart() == 9) {
                editText.setSelection(8);
            }
        } else if (length > 3) {
            s.insert(3, String.valueOf(space));
            if (editText.getSelectionStart() == 4) {
                editText.setSelection(3);
            }
        }
        editText.addTextChangedListener(myTextWatch);
    }

然后为了防止 Editable 的删除 、插入操作调用监听进入死循环,我们可以先移除监听,然后完成相关操作后果再添加。上述做法也是先对输入的字符串进行去除空格进行111 1111 1111这种格式进行格式化,不过这种还是需要处理光标的问题,因为你刚好中间输入或者删除,后面一位是空格并且字符串去掉空格长度过后大于3的话,光标插入就自动在空格后面而不在字符串后面,删除呢就不能删除中间的空格,删除了一位空格又马上插入了一个空格,显然是不对的。
所以我们上述代码做了如下处理:

if (editText.getSelectionStart() == 4) {
    editText.setSelection(3);
 }

 if (editText.getSelectionStart() == 9) {
     editText.setSelection(8);
 }

只要光标在空格后面就自动移到字符串的后面,就像下面这种:
手机号码、银行卡输入添加空格_第1张图片
当然也可以不自动移动,只需要判断是删除的时候不添加这段代码即可,什么时候是删除的时候呢,就是 onTextChanged(CharSequence s, int start, int before, int count) 中 count 等于0的时候。

实现银行卡呢,那就更简单了,只需要对每一个四位添加空格,乃至推广到间隔几个数字的空格,代码如下:

private static final int divide = 4;

         if (length > 0 && length / divide > 0) {
                for (int i = 0; i < length / divide; i++) {
                    s.insert((i + 1) * divide + i, String.valueOf(space));
                    if (editText.getSelectionStart() == (i + 1) * divide + 1 + i) {
                        editText.setSelection((i + 1) * divide + i);
                    }
                }
            }

代码思路跟上面是一样的,没有什么好解释的了,遇到间隔5个、6个,重新设置一下参数就好了,所以最终成果是这样的:

电话号码空格输入:
手机号码、银行卡输入添加空格_第2张图片

银行卡号输入:
手机号码、银行卡输入添加空格_第3张图片

三、结束语

这篇文章越写感觉这个需求不难,但是我还是记录一下吧,有问题的或者有更好的方法欢迎大家吐槽,哈哈。最近感觉博客有的页面广告等干扰越来越多了,太影响阅读了,给大家推荐一款我发现的 Chrome 插件,简阅,专注阅读,地址在此 简阅。

你可能感兴趣的:(Android开发)