欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android输入字符限制

程序员文章站 2022-03-11 22:53:24
公司项目登录模块的密码需要对输入字符进行限制,只能输入数字、字母和一些普通的字符(电脑键盘按键上面显示的那些英文字符),不允许输入中文、中文符号、特殊符号等一些其他字符。先贴一张百度百科里的一张ASCII码表:从这张表格可以看到,电脑键盘上的那些字符对应的ASCII码数值范围在33 ~ 126之间,这样处理起来就方便了,用户输入时,我们只需要过滤这个区间的字符显示到密码输入框即可,之前有用过TextWather来监听输入的内容,实践后发现这个不好用,通过监听到内容里面有非法字符后还需要把合法的设置回去...

公司项目登录模块的密码需要对输入字符进行限制,只能输入数字、字母和一些普通的字符(电脑键盘按键上面显示的那些英文字符),不允许输入中文、中文符号、特殊符号等一些其他字符。

先贴一张百度百科里的一张ASCII码表:
android输入字符限制
从这张表格可以看到,电脑键盘上的那些字符对应的ASCII码数值范围在33 ~ 126之间,这样处理起来就方便了,用户输入时,我们只需要过滤这个区间的字符显示到密码输入框即可,之前有用过TextWather来监听输入的内容,实践后发现这个不好用,通过监听到内容里面有非法字符后还需要把合法的设置回去给EditText,这会导致光标位置发生变化,如用户定位到密码中间的位置输入非法字符,我们禁止了非法字符后,光标跑到最前面了。

后来想到xml中inputType属性可以设置输入的类型,也就是实现了限制输入的字符类型,于是想到查找这个属性对应的类方法,然后查看其源码实现,发现它里面用到了很多监听器,有好几个是实现了InputFilter接口的,看接口名字也很好理解,就是用于过滤输入的字符内容的,它与TextWather不同,TextWather是已经接收了输入的值并显示到了EditText上,然后把输入后的内容告诉你,而过滤器是先过滤,过滤出来的内容才显示到EditText上面,过滤器中的各个参数官方说的不太明白,或许是英文不好,不能很好理解,然后看官方上InputFilter的一些实现类,比如 InputFilter.AllCaps用于把字母变大写,InputFilter.LengthFilter用于限制输入的长度,看过了这些还不是很理解其接口的各参数的真正含意,于是只能自己打印参数自己分析其功能,也不知道是这不是这样的,总之解决了我的问题,代码如下:

/** 密码输入过滤器,过滤用户输入的字符序列,包含粘贴的字符序列。只允许ASCII码值为 33 ~ 126 范围内的字符 */
class PasswordTextFilter: InputFilter {

    /**
     * 过滤用户输入的字符序列,包含粘贴的字符序列。只允许ASCII码值为 33 ~ 126 范围内的字符
     * @param source 用户新输入的字符序列或粘贴的字符序列(如果是输入的话是一个字符,如果粘贴的话可能是多个字符)
     * @param start source字符序列中start ~ end(不包含end)范围内的字符序列是新输入的或粘贴过来的
     * @param end source字符序列中start ~ end(不包含end)范围内的字符序列是新输入的或粘贴过来的
     * @param dest 原来的字符序列。文档说不建议对这个字符序列对象进行任何的更改,只能用于检查。经过实验,我发现改了内容也没见发生有任何变化。
     * @param dstart dest字符序列中dstart ~ dend(不包含dend)范围内的字符序列被删除了
     * @param dend dest字符序列中dstart ~ dend(不包含dend)范围内的字符序列被删除了
     * @return 返回新的字符序列来替换source字符序列,返回null表示接受原来的内容,返回空字符串则表示禁止本次输入(即输入的字符内容不会显示到EditText上)
     */
    override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int): CharSequence? {
        return if (end - start > 0) {
            // 这种情况说明是用户输入了新的内容,则进行过滤,只保留ASCII码值为 33 ~ 126 范围内的字符
            source.subSequence(start, end).filter { c: Char -> c.toInt() in 33..126 }
        } else {
            // 这种情况说明是删除操作,删除操作时返回任何的内容好像都没用,比如返回888并不会在输入框看到888
            null
        }
    }
}

搞Android就是这样,有时候代码就几行,但是需要花好多时间来了解其功能,上面我们自定义了一个过滤器,用来过滤出我们想要的字符,以防非法字符的输入。最后把这个过滤器用到EditText身上即可,如下:

passwordEditText.filters = arrayOf(PasswordTextFilter())

本文地址:https://blog.csdn.net/android_cai_niao/article/details/108131987