2路数据绑定不适用于liveData

时间:2018-07-31 07:10:30

标签: android android-livedata 2-way-object-databinding

我想通过LiveData使用2向数据绑定。但是更改editText值不会更新显示user.name的textView。 我的代码有什么问题?我使用android studio 3.3金丝雀3并通过以下代码在gradle.properties中启用了数据绑定v2:

android.databinding.enableV2=true

模型数据类:

data class User(var name: String)

viewModel类:

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>

更新: 我在此链接上找到了解决方案:

LiveData update on object field change

我设置了此更改并且它起作用:

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()

}

}

并添加新

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)
}

}

1 个答案:

答案 0 :(得分:-1)

我认为问题在于您只更改了用户名的值,而不是LiveData的值,因此textview不会根据它更改。

看看您的代码有什么变化,在这种情况下可以使用2向数据绑定。

更改ViewModel

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

    init {
        user.value = "Ali"
    }
}

并更改布局

<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>