开发中经常遇到禁止输入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<InputFilter>()
var doAfter :((s:String)->Unit)? = null
private var mContext: Context? = null
constructor(context: Context?) : this(context,null){
// initEditText(context)
}
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 }
}
private 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<InputFilter>(forbitFilterArry.count())
for ( i in 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 (i in 0 until len) {
val codePoint = source[i]
if (!isEmojiCharacter(codePoint)) { //如果不能匹配,则该字符是Emoji表情
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() >= 0x20 && codePoint.toInt() <= 0xD7FF ||
codePoint.toInt() >= 0xE000 && codePoint.toInt() <= 0xFFFD || codePoint.toInt() >= 0x10000 && codePoint.toInt() <= 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" />
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代码

网友评论