Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bindable must be on a member in an Observable class

I'm new in data binding , this is my code but I get this error on building

class DatabindingViewModel :ViewModel() {

val currentFruitName:LiveData<String>
    get() = FakeRepository.currentName

fun changeNameOnClick()=FakeRepository.changeRandomFoodName()

//two way LiveData
@Bindable
val editTextContext= MutableLiveData<String>()

private val _displayEditTexfContent=MutableLiveData<String>()
val displayEditTexfContent:LiveData<String>
    get()=_displayEditTexfContent

fun onDisplayEtText(){
    _displayEditTexfContent.value=editTextContext.value
}

this is my xml layout code :

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

    <data>
        <variable
            name="binding"
            type="ir.persiandesigners.myapplication.databinding.viewmodel.DatabindingViewModel" />
    </data>

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

        <TextView
            android:id="@+id/textView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="50dp"
            android:layout_marginLeft="50dp"
            android:layout_marginTop="32dp"
            android:layout_marginEnd="50dp"
            android:layout_marginRight="50dp"
            android:text="@{binding.currentFruitName}"
            android:textAppearance="@style/TextAppearance.AppCompat.Display1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="32dp"
            android:onClick="@{()->binding.changeNameOnClick()}"
            android:text="Get Random  Name"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView" />

        <EditText
            android:id="@+id/editText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="60dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:text="@={binding.editTextContext}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="24dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:onClick="@{()->binding.onDisplayEtText()}"
            android:text="Change Display Text"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/editText" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

this is the code I've in the activity:

val viweModel= ViewModelProviders.of(this)
            .get(DatabindingViewModel::class.java)

    DataBindingUtil.setContentView<ActvitiyDatadindingBinding>(
            this,R.layout.actvitiy_datadinding)
            .apply {
                this.setLifecycleOwner( this@DataBindingAct)
                this.binding=viweModel
            }

    viweModel.editTextContext.observe(this, Observer{
        Toast.makeText(this@DataBindingAct,it ,Toast.LENGTH_LONG).show()
    })

when I want to build the project and run it , I get this error :

e: error: Bindable must be on a member in an Observable class. DatabindingViewModel is not Observable

could you help me ?

I've tried to clean the project , rebuild and so on but there is an error in my code that I couldn't find

could you help me ?

like image 663
Navid Abutorab Avatar asked Jun 11 '19 12:06

Navid Abutorab


People also ask

What is the use of Baseobservable in Android?

Adds a callback to listen for changes to the Observable. Notifies listeners that all properties of this instance have changed. Notifies listeners that a specific property has changed. Removes a callback from those listening for changes.

What is Data Binding in Android MVVM?

The Data Binding Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically. Layouts are often defined in activities with code that calls UI framework methods.

What is Br in Data Binding Android?

} Note: The Data Binding Library generates a class named BR in the module package which contains the IDs of the resources used for data binding. In the example above, the library automatically generates the BR. item variable.


2 Answers

Just remove @Bindable annotation from Viewmodel and your code will run successfully and error will be resolved.

The @Bindable annotation should only be be applied when you are accessing getter method while extending BaseObservable class which itself implements Observable interface for observing data.

Here LiveData itself is an observable data holder class

So, you don't need to implement @Bindable and BaseObservable class for observing data.

docs: https://developer.android.com/reference/android/databinding/Bindable

I hope things are clear now..

like image 77
master Gaurav Avatar answered Sep 18 '22 09:09

master Gaurav


You have to implement Observable Interface and add its methods

here is mine,

class MainViewModel: ViewModel(), Observable { 

private val callbacks: PropertyChangeRegistry by lazy { PropertyChangeRegistry()}

    override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
        callbacks.add(callback)
    }

    override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
        callbacks.remove(callback)
    }
}// class ends here
like image 32
Sumit Jangir Avatar answered Sep 19 '22 09:09

Sumit Jangir