Friday, 7 May 2021

Data Binding EditText set null was replaced by set empty String

I have created a sample project which can reproduce this problem.

Expected Behaviour

I have an EditText. I have a TextView which shows the error about the input in this EditText. I also have a reset button which can reset the input inside EditText.

I want to achieve the below:

  1. Use two-way Data Binding
  2. Before user enters anything, no error should be shown.
  3. When user enters something and deleted them, an error saying Input cannot be empty should be shown.
  4. When user clicks Reset, the input inside EditText should be cleared.
  5. When user clicks Reset, there should be no error shown.

How I tried to do it

Layout xml: (For simplicity I am showing only the EditText and TextView here. You can go to the sample project for a full version)

        <EditText
                android:id="@+id/et"
                android:layout_height="wrap_content"
                android:layout_marginEnd="16dp"
                android:layout_marginStart="16dp"
                android:layout_marginTop="16dp"
                android:layout_width="0dp"
                android:text="@={vm.userInput}"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

        <TextView
                android:id="@+id/tvError"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                app:layout_constraintTop_toBottomOf="@id/et"
                app:layout_constraintStart_toStartOf="@id/et"
                app:layout_constraintEnd_toEndOf="@id/et"
                tools:text="I am some error"
                android:text="@{vm.errorText}"
                android:textColor="@android:color/holo_red_dark"
                android:visibility="@{vm.isErrorVisible() ? View.VISIBLE : View.GONE}" />

The ViewModel:

    val userInput = MutableLiveData<String?>(null)
    val errorText = userInput.map { input ->
        if (input?.isBlank() == true) {
            "This field cannot be empty"
        } else {
            ""
        }
    }
    val isErrorVisible = errorText.map { errorText.value?.isNotBlank() == true }

    fun onReset() {
        userInput.value = null
    }

Observed Behavior

1, 2, 3 are achieved. 4 cannot be achieved - when I click Reset, the error is displayed.

More observations

  1. By debugging, I can observe that userInput.value = "" has been called after onReset(). Probably by the Data Binding library? Which should also be the cause of this whole problem.

  2. If I click reset() when the input is already empty, the error will not be shown. i.e. Point 1 above does not happen if the input is empty.

The Question

How can I achieve 4?



from Data Binding EditText set null was replaced by set empty String

No comments:

Post a Comment