0

When I write this code with a normal editext, It works fine, when I do t with the TextInputLayout/TextInputEditText, it does not work. What I want is the input field(EditText) to observe the string via data binding.

I've tried obersving it via code and via xml

XML

<com.google.android.material.textfield.TextInputLayout
            android:id="@+id/new_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/new_passwod"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:layout_marginTop="15dp"
            app:passwordToggleEnabled="true"

            >

    <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword"
            android:text="@={changePasswordViewModel.newPassword}"
            app:onFocusChange="@{handler.newPasswordFocusChanged}"
            app:onTextChange="@{handler.passwordTextChanged}"
    />

ViewModel


//Fields
 val currentPassword = MutableLiveData<String>()
 val newPassword = MutableLiveData<String>()
 val confirmNewPassword = MutableLiveData<String>()

//Handler
inner class Handler {
val newPasswordFocusChanged = object : FocusChangedListener {
            override fun focusChanged(hasFocus: Boolean) {
                if (!hasFocus && !newPassword.value.validateRegex(accountFormConfiguration.getPasswordRegex())) {
                    _status.value = ModelEvent(ChangePasswordStatus.NewPasswordValidationError(errorMessage = accountFormConfiguration.getPasswordRegexError(), isErrorEnabled = true))
                } else {
                    _status.value = ModelEvent(ChangePasswordStatus.NewPasswordValidationError(null, isErrorEnabled = false))
                }
            }
        }
}

sealed class ChangePasswordStatus {
        data class NewPasswordValidationError(val errorMessage: String?, val isErrorEnabled: Boolean) : ChangePasswordStatus()
        data class ConfirmNewPasswordValidationError(val errorMessage: String) : ChangePasswordStatus()
        data class SamePasswordValidationError(val errorMessage: String) : ChangePasswordStatus()
        data class Failure(val errorMessage: String) : ChangePasswordStatus()
    }

//BindinigAdapter

@BindingAdapter("app:onFocusChange")
fun onFocusChange(text: EditText, focusChangedListener: FocusChangedListener) {
    text.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
        focusChangedListener.focusChanged(hasFocus)
    }
}

View handling status

private fun handleStatus(status: ChangePasswordStatus?) {
        when(status) {
            is ChangePasswordStatus.NewPasswordValidationError -> {
                binding.newPassword.error = status.errorMessage
                binding.newPassword.isErrorEnabled = status.isErrorEnabled
            }

Extension function

fun String?.validateRegex(regex: String?): Boolean {
    if (this.isNullOrBlank() || regex.isNullOrBlank()) return false
    val pattern = Pattern.compile(regex)
    val matcher = pattern.matcher(this)
    return matcher.matches()
}
EmmaneulO1
  • 63
  • 1
  • 5

1 Answers1

0

Have you done setLifecycleOwner() in your fragment binding?

The_Martian
  • 3,684
  • 5
  • 33
  • 61