开发中经常遇到禁止输入emoji、空格或者特殊字符的需求,每次使用都用正则表达式完成一次校验,校验多了感觉很臃肿,
于是暂时完成了一个可选择禁止输入以上内容的Edittext,有需要可以直接使用。
1.属性
<declare-styleable name="FilterEditext">
<attr name="allowEmoji" format="boolean">
<attr name="allowSpace" format="boolean">
<attr name="allowSpecial" format="boolean">
</declare-styleable>
2.代码
class FilterEditext :EditText {
private var isAllowEmoji =true
private var isAllowSpace =true
private var isAllowSpecial =true
private var forbitFilterArry =arrayListOf()
var doAfter :((s:String)->Unit)? =null
private var mContext:Context? =null
constructor(context:Context?) :this(context,null)
constructor(context:Context?, attrs: AttributeSet?) :super(context, attrs){
val obtainStyledAttributes = context?.obtainStyledAttributes(attrs, R.styleable.FilterEditext)
obtainStyledAttributes?.apply {
isAllowEmoji = getBoolean(R.styleable.FilterEditext_allowEmoji,true)
isAllowSpace = getBoolean(R.styleable.FilterEditext_allowSpace,true)
isAllowSpecial = getBoolean(R.styleable.FilterEditext_allowSpecial,true)
if (!isAllowEmoji){
forbitFilterArry.add(emojiFilter)
}
if (!isAllowSpace){
forbitFilterArry.add(spaceFilter)
}
if (!isAllowSpecial){
forbitFilterArry.add(specialFilter)
}
recycle()
}
initEditText(context)
}
constructor(context:Context?, attrs: AttributeSet?, defStyleAttr:Int) :this(context, attrs)
constructor(context:Context?, attrs: AttributeSet?, defStyleAttr:Int, defStyleRes:Int) :this(context, attrs)
private val specialFilter =InputFilter { source, start, end, dest, dstart, dend->
if (isSpecialText(source.toString())) {
Toast.makeText(mContext, "不支持特殊字符", Toast.LENGTH_SHORT).show()
""
}else{
null
}
}
private val spaceFilter=InputFilter { source, start, end, dest, dstart, dend->
if (source.equals(" ")) {
Toast.makeText(mContext, "不支持空格", Toast.LENGTH_SHORT).show()
}
if (source.equals(" ")){"" }else{null }
}
val emojiFilter =InputFilter { source, start, end, dest, dstart, dend-> if (containsEmoji(source.toString())){"" }else{null }}
// 初始化edittext 控件
private fun initEditText(context:Context?) {
this.mContext = context
val forbitFilters =arrayOfNulls(forbitFilterArry.count())
for ( iin 0 until forbitFilterArry.count()){
forbitFilters[i] =forbitFilterArry[i]
}
filters = forbitFilters
addTextChangedListener(object :TextWatcher{
override fun afterTextChanged(s: Editable?) {
doAfter?.invoke(s.toString())
}
override fun beforeTextChanged(s: CharSequence?, start:Int, count:Int, after:Int) {
}
override fun onTextChanged(s: CharSequence?, start:Int, before:Int, count:Int) {
}
})
}
/**
* 检测是否有emoji表情
*
* @param source
* @return
*/
private fun containsEmoji(source:String):Boolean {
val len = source.length
for (iin 0 until len) {
val codePoint = source[i]
if (!isEmojiCharacter(codePoint)) {
Toast.makeText(mContext, "不支持输入Emoji表情符号", Toast.LENGTH_SHORT).show()
return true
}
}
return false
}
/**
* 判断是否是Emoji
*
* @param codePoint 比较的单个字符
* @return
*/
private fun isEmojiCharacter(codePoint:Char):Boolean {
return codePoint.toInt() ==0x0 || codePoint.toInt() ==0x9 || codePoint.toInt() ==0xA ||
codePoint.toInt() ==0xD || codePoint.toInt()in 0x20..0xD7FF ||
codePoint.toInt()in 0xE000..0xFFFD || codePoint.toInt()in 0x10000..0x10FFFF
}
private fun isSpecialText(codePoint:String):Boolean{
val speChat="[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]"
val pattern =Pattern.compile(speChat)
val matcher = pattern.matcher(codePoint)
return matcher.find()
}
}
3.使用
<FilterEditext
android:layout_width="match_parent"
android:layout_height="match_parent"
app:allowEmoji="false"
app:allowSpecial="false"
app:allowSpace="false" />
4.额外
filterEditext .doAfter ={
//lambda 这里获取输入后字符串,偶尔用于计算字符长度
}
使用java代码可以在studio中tools->kotlin->show kotlin bytecode ->Decompile 可以转换java代码
https://github.com/AndroidxXiaobai/FiltterEditText
网友评论