How do I use InputFilter to limit characters in an EditText in Android?

后端 未结 20 1127
慢半拍i
慢半拍i 2020-11-22 04:23

I want to restrict the chars to 0-9, a-z, A-Z and spacebar only. Setting inputtype I can limit to digits but I cannot figure out the ways of Inputfilter looking through the

相关标签:
20条回答
  • 2020-11-22 05:17

    You can specify wanted characters in a regex and use it in InputFilter:

    val regex = Regex("[a-zA-Z\\d ]")
        
    editText.filters = arrayOf(InputFilter { source, _, _, _, _, _ ->
        source.filter { regex.matches(it.toString()) }
    })
    

    Notice, I didn't used \w character class, because it includes underscore _

    0 讨论(0)
  • 2020-11-22 05:18

    I have the same answer in Kotlin:

    /**
     * Returns the filter of the editText'es CharSequence value when [filterType] is:
     * 1 -> letters; 2 -> letters and digits; 3 -> digits;
     * 4 -> digits and dots
     */
    class InputFilterAlphanumeric(private val filterType: Int): InputFilter {
        override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence {
            (source as? SpannableStringBuilder)?.let {sourceAsSpannableBuilder  ->
                for (i in (end - 1) downTo start) {
                    val currentChar = source[i]
                    when(filterType) {
                        1 -> {
                            if (!currentChar.isLetter() && !currentChar.isWhitespace()) {
                                sourceAsSpannableBuilder.delete(i, i + 1)
                            }
                        }
                        2 -> {
                            if (!currentChar.isLetterOrDigit() && !currentChar.isWhitespace()) {
                                sourceAsSpannableBuilder.delete(i, i + 1)
                            }
                        }
                        3 -> {
                            if (!currentChar.isDigit()) {
                                sourceAsSpannableBuilder.delete(i, i + 1)
                            }
                        }
                        4 -> {
                            if (!currentChar.isDigit() || !currentChar.toString().contains(".")) {
                                sourceAsSpannableBuilder.delete(i, i + 1)
                            }
                        }
                    }
                }
                return source
            } ?: run {
                val filteredStringBuilder = StringBuilder()
                for (i in start until end) {
                    val currentChar = source?.get(i)
                    when(filterType) {
                        1 -> {
                            if (currentChar?.isLetter()!! || currentChar.isWhitespace()) {
                                filteredStringBuilder.append(currentChar)
                            }
                        }
                        2 -> {
                            if (currentChar?.isLetterOrDigit()!! || currentChar.isWhitespace()) {
                                filteredStringBuilder.append(currentChar)
                            }
                        }
                        3 -> {
                            if (currentChar?.isDigit()!!) {
                                filteredStringBuilder.append(currentChar)
                            }
                        }
                        4 -> {
                            if (currentChar?.isDigit()!! || currentChar.toString().contains(".")) {
                                filteredStringBuilder.append(currentChar)
                            }
                        }
                    }
                }
                return filteredStringBuilder
            }
        }
    }
    

    and get the class with an Extension function:

    fun EditText.filterByDataType(filterType: Int) {
        this.filters = arrayOf<InputFilter>(InputFilterAlphanumeric(filterType))
    }
    
    0 讨论(0)
提交回复
热议问题