-2

I want use 2-way dataBinding by LiveData. but change editText value not update textView that show user.name. what is wrong by my code? I use android studio 3.3 canary 3 and enable data binding v2 in gradle.properties by this code:

android.databinding.enableV2=true

model data class:

data class User(var name: String)

viewModel class:

class MainViewModel : ViewModel() {
val user =  MutableLiveData<User>()

init {
    user.value = User("ali")
}

}

mainActivity:

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val activityMainBinding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
    val viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
    activityMainBinding.setLifecycleOwner(this)
    activityMainBinding.viewModel = viewModel
}

}

<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="viewModel"
        type="com.example.hoseinkelidari.databindingsample.MainViewModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="60dp"
        android:layout_marginEnd="8dp"
        android:text="@={viewModel.user.name}"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:text="@{viewModel.user.name}"
        app:layout_constraintBottom_toTopOf="@+id/editText"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Update: I found solution at this link:

LiveData update on object field change

I set this change and it work:

class User : BaseObservable() {
@get:Bindable
var firstName: String? = null
    set(name) {
        field = firstName
        notifyPropertyChanged(BR.firstName)
    }

}

class MainViewModel : ViewModel() {

var user = CustomMutableLiveData<User>()

init {
    user.value = User()

}

}

and add new

class CustomMutableLiveData<T : BaseObservable> : MutableLiveData<T>() {

internal var callback: Observable.OnPropertyChangedCallback = object : Observable.OnPropertyChangedCallback() {
    override fun onPropertyChanged(sender: Observable, propertyId: Int) {

        //Trigger LiveData observer on change of any property in object
        value = value

    }
}

override fun setValue(value: T?) {
    super.setValue(value)

    //listen to property changes
    value!!.addOnPropertyChangedCallback(callback)
}

}

h.kelidari
  • 800
  • 1
  • 11
  • 20
  • Where are you setting `viewModel.user.name` to it's new value when your enter some text in `EditTex`t? – hardartcore Jul 31 '18 at 07:33
  • @hardartcore not set. 2-way data binding not should do it? android:text="@={viewModel.user.name}" – h.kelidari Jul 31 '18 at 07:57
  • Here is a nice article how it should be done: https://medium.com/@fabioCollini/android-data-binding-f9f9d3afc761 – hardartcore Jul 31 '18 at 07:59
  • @hardartcore I want use Live data. this example not use LiveData and use a old way! – h.kelidari Jul 31 '18 at 08:24
  • 1
    Ok, so here is another link which should help you : ) https://github.com/googlesamples/android-databinding . You should search more for information before posting a question here. It's not just paste the same field in two places and voala. – hardartcore Jul 31 '18 at 08:30
  • This example not use LiveData, I searched alot before posting question, but not found any example by liveData. Until found this that solve my problem https://stackoverflow.com/questions/48020377/livedata-update-on-object-field-change#48194074 – h.kelidari Jul 31 '18 at 11:38

1 Answers1

-1

I think the problem is that you only change the value of user's name, not the value of LiveData, so textview is not changing according to it.

Take a look at some change in your code, and 2-way dataBinding is worked in this case.

Change the ViewModel

class MainViewModel : ViewModel() {
    val user =  MutableLiveData<String>()

    init {
        user.value = "Ali"
    }
}

and change the layout

<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="viewModel"
            type="com.example.hoseinkelidari.databindingsample.MainViewModel" />
    </data>

    <android.support.constraint.ConstraintLayout

        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <EditText
            android:id="@+id/editText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="60dp"
            android:layout_marginEnd="8dp"
            android:text="@={viewModel.user}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            android:text="@{viewModel.user}"
            app:layout_constraintBottom_toTopOf="@+id/editText"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </android.support.constraint.ConstraintLayout>
</layout>
Mumi
  • 341
  • 3
  • 11