Когда первая буква не принята фильтром ввода, запись не будет принята - PullRequest
1 голос
/ 07 января 2020

Это аналогичная, но несколько иная проблема, чем вопрос, который я задал здесь: Когда мой источник InputFilter входит в состав spannable, источник не удаляет символы, которые я отфильтрую

В моем примере я делаю входной фильтр для проверки канадских почтовых индексов.

У меня есть аннотация здесь:

abstract class MyInputFilter : InputFilter {

protected abstract fun String.isValid(): Boolean

private fun getFinalResultOfChange(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int): CharSequence {
    return dest.replaceRange(dstart, dend, source.subSequence(start, end))
}

private fun getNoChangeResult(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int): CharSequence {
    val initialSubSequence = dest.subSequence(dstart, dend)
    return try {
        if (source is Spanned) {
            val spannable = SpannableString(initialSubSequence)
            TextUtils.copySpansFrom(source, start, end, null, spannable, 0)
            spannable
        } else {
            initialSubSequence
        }
    } catch (e: Exception) {
        initialSubSequence
    }
}

override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence? {
    if (source == null || dest == null) {
        return null
    }

    val input = getFinalResultOfChange(source, start, end, dest, dstart, dend).toString()

    return if (input.isValid()) {
        null // Allow the edit to proceed unchanged.
    } else {
        getNoChangeResult(source, start, end, dest, dstart, dend)
    }
}

}

, которую я наследую и переопределяю isValid для всех моих входных фильтров. Этот фильтр ... странный, но появился на основе вопроса, связанного выше, и несколько решил проблему, которая у меня была.

Это наивно из-за моего намерения быть преднамеренным, но вот фильтр CAN:

    private val patterns = listOf(
        "^(?!.*[DFIOQUdfioqu])[A-VXYa-vxy]$",
        "^(?!.*[DFIOQUdfioqu])[A-VXYa-vxy][0-9]$",
        "^(?!.*[DFIOQUdfioqu])[A-VXYa-vxy][0-9][A-Za-z]$",
        "^(?!.*[DFIOQUdfioqu])[A-VXYa-vxy][0-9][A-Za-z][0-9]$",
        "^(?!.*[DFIOQUdfioqu])[A-VXYa-vxy][0-9][A-Za-z][0-9][A-Za-z]$",
        "^(?!.*[DFIOQUdfioqu])[A-VXYa-vxy][0-9][A-Za-z][0-9][A-Za-z][0-9]$"
    )

    override fun String.isValid(): Boolean {
        return when (length) {
            0 -> true
            1, 2, 3, 4, 5, 6 -> this.matches(Regex(patterns[length - 1]))
            else -> false
        }
    }

Теперь у меня новая проблема. Если самый первый введенный символ является недопустимой буквой, клавиатура продолжает загружать символы в «слово» и пытается повторно отправить их. Поэтому, если я наберу

D

, ничего не будет введено правильно. Но, если я наберу

DA

, все равно ничего не будет введено, и мой телефон попытается автоматически предложить слово «da». Если я не щелкну предложенное слово или клавишу возврата, чтобы очистить, поле НЕ будет принимать никаких вводимых данных, но клавиатура будет продолжать «ставить в очередь» слово со всеми набранными мной буквами. Если я введу плохой символ в ЛЮБУЮ ДРУГУЮ позицию, пока первый символ был принят, это работает. Телефон не начинает «ставить в очередь» слово на клавиатуре, и я могу сразу ввести правильный символ.

Также важно: цифры не вызывают проблемы. Клавиатура не пытается начать «строить» слово из числа, поэтому, если я наберу

1A

, то в поле вводится «A» без проблем.

Я могу почти ни у кого не было таких проблем с фильтрами ввода и включаемым, а не включаемым вводом CharSequence, но клавиатура строит слово и пытается передать все так, как я не понимаю. Я попробовал это на GBoard на OnePlus 6T, а также на стандартной клавиатуре Samsung Samsung Tab E по умолчанию, так что это не похоже на отдельную ошибку клавиатуры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...