Databinding и BaseObserver – Android MVVM

У меня есть текстовое поле, которое привязано к модели представления, например, xml, и я хочу, чтобы пользовательский интерфейс обновлял поле txtProvider при щелчке по карточному окну. Как мне уведомить об изменении вида из моей модели просмотра?

<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 

Я получил его работу в Kotlin с помощью @Bindable в viewmodel, как показано ниже. Попробовал немного понять, как использовать @Bindable в синтаксисе Kotlin. Свойство BR.provider не создавалось, пока я не получил синтаксис @Bindable.

 fun onClickModel(): View.OnClickListener { val viewOnClick = View.OnClickListener { route!!.provider = "name changed" notifyPropertyChanged(BR.provider) } return viewOnClick } val provider: String @Bindable get() { Log.d("Utils", "get property") return route!!.provider!! } 

Я буду использовать синтаксис java, потому что я не так свободно говорю с kotlin:

Чтобы включить привязку, вам необходимо объявить MyModel или provider с помощью DataBinding . Используйте @Bindable на getter и вызовите notifyPropertyChanged в notifyPropertyChanged :

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

или сделать MyModel расширением BaseObservable или, поскольку у вас есть viewmodel, создайте ObservableField<String> или даже ObservableField<MyModel> :

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

Задайте значение в конструкторе вашей модели просмотра, создайте геттер и укажите это в своем xml .

В файле MyModel.kt

 class MyModel( @get:Bindable var provider: String = "" ) : BaseObservable() { fun updateText(str:String){ provider = str notifyPropertyChanged(BR.counter) } } 

а затем в вашем layout.xml

 android:onClick="@{() -> myModel.updateText(`YOUR TEXT`)}" 

Rebuild свой проект, если вы не можете получить BR.counter автозаполнения BR.counter

Это может быть скорее проблема Котлина. Когда я инициализирую провайдера String как ObservableField как

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

Я получаю сообщение об ошибке во время выполнения java.lang.String не может быть передан в android.databinding.ObservableField

Я попробую разместить его на сайте обсуждения kotlin и найти ответы.