Не срабатывает часть кода, отвечающая за то, чтобы не давать вводить определённые символы в определенную позицию текста

ТЗ: для защиты от случайных нажатий не на те клавиши нужна проверка значения, например, 3-ей и 4-ой цифры в строке, чтобы 3 равнялась 0 или 1, а 4-я - 1 или 2. Если это не так - то выполнение кода должно просто приостанавливаться и не давать вводить следующие знаки. Условие не срабатывает если объединить, по отдельности срабатывает, но выполнение кода не прерывается. Может дело в цикличности addTextChangedListener

введите сюда описание изображения

 slovo.setOnFocusChangeListener { _: View, hasFocus ->
     inputTextWatch()
 }

fun inputTextWatch() {

    slovo.addTextChangedListener(object : TextWatcher {
        var isAdded = true

        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
            isAdded = count < after
        }

        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {

            if (s.length == 4) {
                when (s[3].equals("0".single())) or (s[3].equals("1".single())) {
                    false -> {
                            Toast.makeText(this@MainActivity, "Ошибка ввода", Toast.LENGTH_SHORT).show()
                            return
                    }
                }
            }
        }

        override fun afterTextChanged(s: Editable) {

            if (isAdded) {
                when (s.length) {
                    2 -> s.append(".")
                    5 -> s.append(".")
                }
            }

            var str = s.toString().replace(".", "")
            if (str.length > 2) {
                str = "${str.take(2)}.${str.drop(2)}"
            }
            if (str.length > 5) {
                str = "${str.take(5)}.${str.drop(5)}"
            }
            if (str != s.toString()) {
                s.replace(0, s.length, str)
            }
        }
    } )
}

Ответы (2 шт):

Автор решения: Andrew

Судя по кол-ву ваших сложностей и проблем возникающих с реализацией этого функционала у меня возник вопрос - почему нельзя использовать стандартный datePicker:

введите сюда описание изображения

Эту штуку можно если что кастомизировать и настроить. Добавьте клик слушатель на ваше поле, и просто выводите datepicker:

val dateSetListener = object : DatePickerDialog.OnDateSetListener {
            override fun onDateSet(view: DatePicker, year: Int, monthOfYear: Int,
                                   dayOfMonth: Int) {
                cal.set(Calendar.YEAR, year)
                cal.set(Calendar.MONTH, monthOfYear)
                cal.set(Calendar.DAY_OF_MONTH, dayOfMonth)
                updateDateInView()
            }
        }



DatePickerDialog(this@MainActivity,
                        dateSetListener,
                        // set DatePickerDialog to point to today's date when it loads up
                        cal.get(Calendar.YEAR),
                        cal.get(Calendar.MONTH),
                        cal.get(Calendar.DAY_OF_MONTH)).show()

вот есть туториал и документация. Дальше отключите возможность фокуса на поле для ввода типа такого:

android:clickable="false"
android:focusable="false"
android:cursorVisible="false"

добавить на всякий случай:

android:inputType="date"

вот ещё один туториал на всякий случай. Дальше после выбора даты устанавливаете текст в ваше поле:

private fun updateDateInView() {
        val myFormat = "MM/dd/yyyy" // mention the format you need
        val sdf = SimpleDateFormat(myFormat, Locale.US)
        textview_date!!.text = sdf.format(cal.getTime())
    }

и все. Не нужно будет лепить костыли для отлова того что пользователь ввел и тому подобное. Безусловно ваша попытка реализации тоже интересная, но нужно учитывать что вы данное решение должны будете поддерживать и оптимизировать. Поэтому мне кажется что данное решение тоже решит вашу задачу но будет проще для осознания и поддержки.

→ Ссылка
Автор решения: junior

Здесь:

override fun afterTextChanged(s: Editable) {...` 

следует добавить:

if (s.length == 4) {
    when (s[3].equals("0".single()) || s[3].equals("1".single())) {
        false -> {
            println(s[3])
            Toast.makeText(this@MainActivity, "Ошибка ввода", Toast.LENGTH_SHORT).show()
            slovo.filters = arrayOf(InputFilter.LengthFilter(4))
        }
        true -> slovo.filters = arrayOf(InputFilter.LengthFilter(10))
    }
}

Но есть небольшой нюанс в работе кода. Задам отдельный вопрос, потому что на этот вопрос нашел ответ сам, хоть это возможно и не оптимальное решение.

→ Ссылка