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

4

5

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?

Vagrant answered 3/10, 2019 at 8:48 Comment(1)
make your function return MutableLiveData since LiveData's setValue() is privateBeatnik
M
3

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}".

Meditation answered 3/10, 2019 at 11:3 Comment(0)
J
2

change from

private val _phoneNumber = MutableLiveData<String>()

to

public val _phoneNumber = MutableLiveData<String>()
Judy answered 3/10, 2019 at 9:9 Comment(0)
N
1

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

Noun answered 3/10, 2019 at 9:14 Comment(0)
T
1

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.

Tuscan answered 3/10, 2019 at 14:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.