美文网首页
可选择屏蔽Emoji/空格/特殊字符FilterEditext

可选择屏蔽Emoji/空格/特殊字符FilterEditext

作者: XBYoung | 来源:发表于2019-07-10 11:16 被阅读0次

    开发中经常遇到禁止输入emoji、空格或者特殊字符的需求,每次使用都用正则表达式完成一次校验,校验多了感觉很臃肿,

    于是暂时完成了一个可选择禁止输入以上内容的Edittext,有需要可以直接使用。

    Demo地址

    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代码

    image

    https://github.com/AndroidxXiaobai/FiltterEditText

    相关文章

      网友评论

          本文标题:可选择屏蔽Emoji/空格/特殊字符FilterEditext

          本文链接:https://www.haomeiwen.com/subject/xkmckctx.html