Search code examples
androidrx-java2

Change Visibility of a button if Email & password is not empty using Rxjava


I want to validate a form in a Login Screen when email and password TextInputEditText are there for login functionality. I use ObservableEmailText and ObservablePasswordText with corresponding logic. For that, I use an extension function

Extensions.kt

fun TextInputEditText.checkError(textInputLayout: TextInputLayout, errorMessage: String, isValid: (String)->Boolean): Observable<String> {
    return textChanges()
        .map { it.toString() }
        .doOnNext {
            if (it.isNotEmpty()) {
                textInputLayout.error = if (isValid(it)) null else errorMessage
            }
    }
}

MainActivity.kt

private val emailObservable
        get() = email_edit_text.checkError(email_input_layout, "Invalid Email") {
            viewModel.isEmailValid(it)
        }

private val phoneNumberObservable
        get() = password_edit_text.checkError(password_input_layout, "Invalid Password") {
            viewModel.isPasswordValid(it)
        }

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getLayoutResource())

        compositeDisposable += Observable.combineLatest<String, String, Boolean>(
            emailObservable,
            phoneNumberObservable,
            BiFunction { t1, t2 -> viewModel.isEmailValid(t1) && viewModel.isPasswordValid(t2) }
        ).subscribe({
            if (it) login_button.visibility = View.VISIBLE
        }, {})
}

The problem I am facing is, the button remains to hide for the first time when I didn't fulfill the logic of Email and password. But when I fulfill the logic of email and password, it becomes visible. It is fine. In fact, I also want that. But the problem is when I clear text or do text something which does not fulfill the logic of taking value from TextViews, it remains visible too. How can I solve this issue


Solution

  • That is because once you are making the visibility of your button View.VISIBLE as soon as the logic is fulfilled. But you are never hiding it again if there are changes after that.

    So essentially you are missing an else block in your subscribe part

    compositeDisposable += Observable.combineLatest<String, String, Boolean>(
                emailObservable,
                phoneNumberObservable,
                BiFunction { t1, t2 -> viewModel.isEmailValid(t1) && viewModel.isPasswordValid(t2) }
            ).subscribe({
                if (it) login_button.visibility = View.VISIBLE
                else login_button.visibility = View.GONE // This line is missing
            }, {})