Dark Lord
Dark Lord

Reputation: 425

2 way data binding error for a livedata variable with proper xml binding

I have a loginViewModel for my login Activity, in activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="loginViewModel"
            type="com.example.test.ui.login.LoginViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/login_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <EditText
            android:id="@+id/mobile_number"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:editable="true"
            android:ems="10"
            android:hint="@string/mobile_number_string"
            android:inputType="phone"
            android:textAlignment="center"
            android:text="@={loginViewModel.phoneNumber}"
            app:layout_constraintBottom_toTopOf="@+id/otp_input"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

And in my loginViewModel i have defined my livedata as

class LoginViewModel : ViewModel(){
    private val _phoneNumber = MutableLiveData<String>()
    val phoneNumber : LiveData<String>
        get() = _phoneNumber
}

Now, while building I am getting the following error

The expression \u0027loginViewModelPhoneNumber.getValue()\u0027 cannot be inverted, so it cannot be used in a two-way binding\n\nDetails: There is no inverse for method getValue, you must add an @InverseMethod annotation to the method to indicate which method should be used when using it in two-way binding expressions

All articles that I am reading suggesting this way to implement. Can someone tell me what am I doing wrong here?

Upvotes: 5

Views: 2318

Answers (4)

Pavlo Ostasha
Pavlo Ostasha

Reputation: 16699

There are several issues with the code.

  • you try to use val phoneNumber that is not mutable in two way binding, thus is has only getter so binding class can only read value from field, to receive data from the UI - binding class wants to use setter, but there is no setter present, thus the phoneNumber won't change.

  • for the property that binds phoneNumber you try to use LiveData which is not mutable - you should use MutableLiveData in case you need it to be able to change.

  • if you want to listen to the changes of phoneNumber you need to add LiveData Observer like

phoneNumber.observe{
  val value = it
}

Hope it helps.

Upvotes: 1

solaza
solaza

Reputation: 1291

Unfortunately for two-way data binding you need to use MutableLiveData.

You should remove private on _phoneNumber.

Then change xml to use it android:text="@={loginViewModel._phoneNumber}".

Upvotes: 3

Rahul Jangid
Rahul Jangid

Reputation: 21

change from

private val _phoneNumber = MutableLiveData<String>()

to

public val _phoneNumber = MutableLiveData<String>()

Upvotes: 2

Maksym V.
Maksym V.

Reputation: 2937

You are binding phoneNumber which is a LiveData that does not have any interface for writing value.

Consider removing phoneNumber, and using Kotlin-based approach, with just a public property

Upvotes: 1

Related Questions