Реализация расширения TextWatcher EditText, которое ссылается на другие элементы - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть вопрос об использовании TextWatcher для одного EditText, но который ссылается в секунду EditText. В поиске по SO я нахожу только вопросы, которые задают, как использовать один TextWatcher для нескольких EditText элементов, но это не то, что я пытаюсь сделать.

Мой экран регистрации пользователя включает два EditText элементы, passwordEditText и confirmEditText. Я хочу добавить проверку, которая гарантирует, что оба они одинаковы.

Непосредственно перед тем, как исследовать, как это сделать, я добавил проверку электронной почты в другой элемент EditText. Используя следующий код, который я нашел в блоге Адриана Холла GitHub , я смог создать расширение EditText, которое очень хорошо добавляет проверку электронной почты к элементу EditText.

// Extensions.kt
fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
  this.addTextChangedListener(object: TextWatcher {
    override fun afterTextChanged(s: Editable?) {
      afterTextChanged.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) {}
  })
}

fun EditText.validateEmail(message: String, validator: (String) -> Boolean) {
  this.afterTextChanged {
    this.error = if (validator(it)) null else message
  }
  this.error = if (validator(this.text.toString())) null else message
}

fun String.isValidEmail(): Boolean = this.isNotEmpty() && Patterns.EMAIL_ADDRESS.matcher(this).matches()

Хотя я не полностью использую asp несколько вариантов использования afterTextChanged (они все одинаковые?), Эти расширения позволяют мне написать следующее в моем MainActivty.onCreate:

emailTextField.validateEmail("Valid email address required") { it.isValidEmail() }

Сейчас Я пытаюсь добавить еще один валидатор, который будет проверять, совпадают ли два пароля.

Моя цель написать что-то вроде этого:

confirmTextField.validateContentsMatch("Passwords do not match") { et1, et2 -> et1.contentsEquals(passwordTextField) }

Вот что я начал с

fun EditText.contentsEqual(et: EditText): Boolean {
  val t1 = this.text.toString().trim()
  val t2 = et.text.toString().trim()
  return t1.isNotEmpty() && t1 == t2
}

fun EditText.validateContentsMatch(message: String, validator: (t1: EditText, t2: EditText) -> Boolean) {
  this.afterTextChanged {
    this.error = if (validator(t1, t2)) null else message
  }
  this.error = if (validator(t1, t2)) null else message
}

Это не работает, потому что t1 и t2 отображаются как "неразрешенные ссылки".

Как я могу получить t1 и t2 из определения валидатора в заголовке функции, чтобы быть доступным / используемым в фактическом теле функции?

...