数据绑定和BaseObserver - Android MVVM

时间:2016-10-24 11:08:25

标签: kotlin observer-pattern android-databinding

我有一个文本字段,可以像这里的xml那样数据绑定到视图模型,我希望UI在点击cardView时更新txtProvider字段。 我应该如何通过viewmodel通知对视图的更改?

<layout xmlns:bind="http://schemas.android.com/tools">
<data>
    <variable name="viewmodel"        
              type="io.leapingwolf.myapp.viewmodel.MyViewModel"/>
   <variable
    name="myModel"
    type="io.leapingwolf.myapp.models.MyModel"/>
</data>
    <android.support.v7.widget.CardView 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"   
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:id="@+id/cardView"
        app:cardCornerRadius="5dp"
        app:cardUseCompatPadding="true"
        android:onClick="@{viewmodel.onClickModel}">
        <TextView
            android:id="@+id/txtProvider"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:text="@{myModel.provider}"
            android:textColor="@android:color/black"
            android:textSize="15sp" />
    </android.support.v7.widget.CardView>
</layout>

在MyViewModel(扩展BaseObserver类)中,我有

fun onClickModel() : View.OnClickListener {
        val viewOnClick = View.OnClickListener { v ->
                                myModel!!.provider = "name changed"
                                notifyPropertyChanged(BR.myModel)
                                Toast.makeText(context,"clicked:" + myModel!!.provider , Toast.LENGTH_SHORT).show()}
                                return viewOnClick
        }

我的数据类:

data class MyModel(
        val type: String?,
        var  provider: String? 
) : AutoParcelable

4 个答案:

答案 0 :(得分:2)

我在Kotlin中使用@Bindable在viewmodel中工作如下。请稍等一下,了解如何在Kotlin语法中使用@Bindable。直到我得到@Bindable语法才生成BR.provider属性。

[textField resignFirstResponder];

答案 1 :(得分:1)

我会使用java语法,因为我对kotlin并不熟悉:

您需要使用MyModel声明providerDataBinding以启用绑定。在getter上使用@Bindable,然后在setter中调用notifyPropertyChanged

@Bindable
public String getProvider() {
    return this.provider;
}

public void setProvider(String provider) {
    this.lastName = lastName;
    notifyPropertyChanged(BR.provider);
}

或者使MyModel展开BaseObservable,或者由于您有视图模型,请创建ObservableField<String>甚至是ObservableField<MyModel>

//in your viewmodel:
private ObservableField<MyModel> modelField = new ObservableField<MyModel>();

在viewmodel的构造函数中设置值,创建一个getter并在xml中引用它。

答案 2 :(得分:1)

在MyModel.kt文件中

PUT

然后在你的layout.xml中

class MyModel(
        @get:Bindable
        var provider: String = ""
) : BaseObservable() {
    fun updateText(str:String){
        provider = str
        notifyPropertyChanged(BR.counter)
    }
}
如果您无法获得android:onClick="@{() -> myModel.updateText(`YOUR TEXT`)}" 自动填充工作

,则

Rebuild您的项目

答案 3 :(得分:0)

这可能更像是一个kotlin问题。当我将提供程序String初始化为ObservableField为

var provider = ObservableField<String>()
init{
    provider = route.provider as ObservableField<String>
}

我在运行时遇到错误 java.lang.String无法强制转换为android.databinding.ObservableField

我会尝试将它发布在kotlin讨论网站上并寻求答案。