Не срабатывает часть кода, отвечающая за то, чтобы не давать вводить определённые символы в определенную позицию текста
ТЗ: для защиты от случайных нажатий не на те клавиши нужна проверка значения, например, 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 шт):
Судя по кол-ву ваших сложностей и проблем возникающих с реализацией этого функционала у меня возник вопрос - почему нельзя использовать стандартный 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())
}
и все. Не нужно будет лепить костыли для отлова того что пользователь ввел и тому подобное. Безусловно ваша попытка реализации тоже интересная, но нужно учитывать что вы данное решение должны будете поддерживать и оптимизировать. Поэтому мне кажется что данное решение тоже решит вашу задачу но будет проще для осознания и поддержки.
Здесь:
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))
}
}
Но есть небольшой нюанс в работе кода. Задам отдельный вопрос, потому что на этот вопрос нашел ответ сам, хоть это возможно и не оптимальное решение.

