2016-10-24 5 views
2

Ich habe ein Textfeld, das auf ein Ansichtsmodell wie die XML hier datengebunden ist, und ich möchte, dass die Benutzeroberfläche das txtProvider-Feld bei einem Klick auf die cardView aktualisiert. Wie sollte ich die Änderung der Ansicht von meinem Viewmodel benachrichtigen?Databinding und BaseObserver - Android MVVM

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

In MyViewModel (der sich BaseObserver Klasse), ich habe

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 
     } 

Meine Daten Klasse:

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

Wie funktioniert Ihr Textfeld aussehen? – yennsarah

+0

Der txtProvider in der Layoutdatei ist das Textfeld. – Akshata

+0

Sie haben also keine Variable oder Eigenschaft für den Text in Ihrem Viewmodel ...? – yennsarah

Antwort

1

ich eine Java-Syntax verwendet werden, weil ich das nicht bin fliessend mit kotlin:

Sie müssen Ihre MyModel oder die provider mit 01 deklarierenum die Bindung zu aktivieren. Verwenden Sie einen @Bindable auf Getter und rufen notifyPropertyChanged in der Setter:

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

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

oder machen Sie Ihre MyModelBaseObservable verlängern, oder da Sie eine Ansichtsmodell haben, erstellen Sie eine ObservableField<String> oder sogar ein ObservableField<MyModel>:

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

Set der Wert im Konstruktor deines Viewmodels, erstelle einen Getter und referenziere diesen in deinem xml.

+0

verfügbar ist. Ich habe es in Kotlin mit dem @Bindable im Viewmodel erstellt – Akshata

0

Es könnte mehr ein Kotlin-Problem sein. Als ich den Provider String als ObservableField als

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

initialisieren bekomme ich einen Fehler zur Laufzeit java.lang.String nicht

zu android.databinding.ObservableField gegossen werden Ich versuche, wird es auf der Kotlin Diskussion veröffentlichen Website und suchen Sie nach Antworten.

2

Ich habe es in Kotlin mit der @Bindable im ViewModel wie unten funktioniert.Erschaut mich eine Weile, um zu verstehen, wie @Bindable in Kotlin Syntax zu verwenden. Die Eigenschaft BR.provider wurde nicht generiert, bis ich die @ Bindable-Syntax richtig eingerichtet habe.

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!! 
    } 
1

In Ihrem MyModel.kt Datei

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

und dann in Ihrem layout.xml

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

Rebuild Ihr Projekt, wenn Sie nicht BR.counter zur automatischen Vervollständigung bekommen arbeiten