需求:EdiText只允许输入中文,英文,数字,下划线,横杠,同时初始化需要显示为带*号的手机号如(157****1426)
方式:
一、简单的属性方式(不满足此需求)
android:inputType="textCapCharacters"//前3个输入普通字符
android:inputType="textCapWords"//单词首字母大小
android:inputType="textCapSentences"//仅第一个字母大写
android:inputType="textAutoCorrect"//前两个自动完成
android:inputType="textAutoComplete"//前两个自动完成
android:inputType="textMultiLine"//多行输入
android:inputType="textImeMultiLine"//输入法多行(不一定支持)
android:inputType="textNoSuggestions"//不提示
android:inputType="textUri"//URI格式
android:inputType="textEmailAddress"//电子邮件地址格式
android:inputType="textEmailSubject"//邮件主题格式
android:inputType="textShortMessage"//短消息格式
android:inputType="textLongMessage"//长消息格式
android:inputType="textPersonName"//人名格式
android:inputType="textPostalAddress"//邮政格式
android:inputType="textPassword"//密码格式
android:inputType="numberPassword"//数字密码格式
android:inputType="textVisiblePassword"//密码可见格式
android:inputType="textWebEditText"//作为网页表单的文本格式
android:inputType="textFilter"//文本筛选格式
android:inputType="textPhonetic"//拼音输入格式
android:inputType="number"//数字格式
android:inputType="numberSigned"//有符号数字格式
android:inputType="numberDecimal"//可以带小数点的浮点格式
android:inputType="phone"//拨号键盘
android:inputType="datetime"//日期时间键盘
android:inputType="date"//日期键盘
android:inputType="time"//时间键盘
android:phoneNumber=”true” //输入电话号码
android:password="true" //输入密码
二、digits属性过滤(不满足此需求)
android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"
注:
1、该属性通过罗列满足要求的字符实现过滤,不支持区间表示法,无法罗列出全部中文字符
2、该方式只过滤键盘输入方式,setText任意字符均能显示(即满足显示*但又禁止键盘方式输入)
三、setFilters(满足此需求)
editText.setText("157****1436")
val filter = InputFilter { source, start, end, dest, dstart, dend ->
source.toString().replace("[^a-zA-Z0-9\u4E00-\u9FA5_-]".toRegex(), "")
}
editText.filters = arrayOf(filter)
注:
1、其中source为输入的字符,dest为原先显示的字符,return "" 表示过滤输入内容,return null 表示不过滤输入内容
2、通过正则匹配方式(其中^表示取反;-即可以表示横杠,也可以表示区间;\u4E00-\u9FA5该区间为汉字)
3、设置过滤规则前setText任意字符均可显示,设置之后对键盘输入和setText字符均进行过滤,可以通过editText.filters = arrayOf()取消过滤规则
四、addTextChangedListener(满足需求)
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) { }
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { }
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s != null && count > 0 && editText.tag as? Boolean != true){//存在输入的字符(非删除且非setText操作)
val inputStr = s.subSequence(start, start + count).toString()
val inputStrNew = inputStr.replace("[^a-zA-Z0-9\\u4E00-\\u9FA5_-]".toRegex(), "")
if (inputStr != inputStrNew){//输入不符合要求的字符
val headStr = s.subSequence(0, start).toString()
val tailStr = s.subSequence(start + count, s.length).toString()
editText.tag = true//标识setText而非键盘输入
editText.setText(headStr + inputStrNew + tailStr)
editText.tag = false//重置标识
editText.setSelection(start + inputStrNew.length)//移动光标
}
}
}
})
注:onTextChanged参数s为输入后的值,count为输入字符的个数,通过editText设置tag标识判断是键盘输入还是setText