2017-03-28 3 views
0

Ich arbeite in MVVM Design-Muster. Ich möchte DataBinding oder RXJava verwenden, um die Ansicht zu benachrichtigen, wenn sich das Modell geändert hat. DataBinding kann es innerhalb xml tun. aber ich möchte die Aktivität auf eine Änderung im Modell benachrichtigen und etwas komplizierter machen. Nehmen wir an, ich möchte, dass mein TextView die Farbe ändert, wenn der Text nicht leer ist. können Sie mir helfen, es über DataBinding oder RXJava zu tun?android - mit DataBinding, auf Aktivität statt Layout

hier ist mein Code:

xml

<?xml version="1.0" encoding="utf-8"?> 

<data> 

    <variable 
     name="viewModel" 
     type="edi.com.mydatabindingsimple.MyViewModel" /> 
</data> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <EditText 
     android:id="@+id/editText" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:ems="10" 
     android:inputType="textPersonName" 
     android:text="@={viewModel.txt}" /> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@={viewModel.txt}" /> 

</LinearLayout> 

Aktivität

import android.databinding.DataBindingUtil; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 

import edi.com.mydatabindingsimple.databinding.ActivityMainBinding; 

    public class MainActivity extends AppCompatActivity { 

     MyViewModel viewModel = new MyViewModel(); 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      final ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); 
      binding.setViewModel(viewModel); 
     } 
    } 

Ansichtsmodell

import android.databinding.BaseObservable; 
import android.databinding.Bindable; 



public class MyViewModel extends BaseObservable{ 
    private String txt; 

    @Bindable 
    public String getTxt() { 
     return txt; 
    } 

    public void setTxt(String txt) { 
     this.txt = txt; 
     notifyPropertyChanged(edi.com.mydatabindingsimple.BR.txt); 
    } 

} 
+1

* aber ich möchte die Aktivität über eine Änderung im Modell benachrichtigen und etwas komplizierter machen. *. Warum die Aktivität? Die VM erhält die Änderungen und benachrichtigt die Eigenschaften. Das sollte alles sein. Wenn die Bindung nicht * nativ * unterstützt wird, können Sie '@ BindingAdapter' verwenden, um Ihren eigenen – Blackbelt

+0

Dankeschön für die Antwort Blackbelt hinzuzufügen. Ich las über @BindingAdapter und erkannte, dass es nur in einem Setter verwendet werden kann. aber ich brauche es in einem Getter. für den Fall, dass ich eine boolesche Flagge in meinem Modell haben möchte, die mich anweist, eine View – ediBersh

+0

anzuzeigen/zu verstecken, also fügen Sie 'android: background =" @ {viewModel.textViewColor} "' in Ihrem '' hinzu und fügen Sie @Bindable int getTextViewColor () 'Methode in' MyViewModel' – pskink

Antwort

1

Was können Sie tun, ist ein Callback-Mechanismus schafft eine Methode in Ihrer Aktivität auszulösen. Dies wird das ViewModel zuerst benachrichtigen, aber der Effekt wird derselbe sein.

Sie können eine neue Schnittstelle erstellen (oder es innerhalb des Ansichtsmodell hinzufügen)

public interface ViewModelCallback{ 
    void ActionCallback(); 
} 

In Ihrer Aktivität:

public class MainActivity extends AppCompatActivity implements ViewModelCallback 

In Ihrem Ansichtsmodell

private ArrayList<ViewModelCallback> callbacks = new ArrayList<>(); 

public void notifyCallbacks(){ 
    for(ViewModelCallback c : callbacks){ 
    if(c != null){ 
     c.ActionCallback 
     } 
    } 
} 

public void addCallback(ViewModelCallback c){ 
    callbacks.add(c); 
} 

Anruf notifyCallback nach dem NotifyPropertyChanged(). Und vergessen Sie nicht, Ihre Tätigkeit als Rückruf in onCreate

viewModel.addCallback(this) 

Sie es auch in onDestroy entfernen sollte hinzuzufügen.

+0

danke, aber ich möchte nicht, dass mein Ansichtsmodell einen Verweis auf die Aktivität hat. es ist gegen die MVVM-Prinzipale. – ediBersh

+0

Ich bin mir nicht sicher, das ist nur ein Rückruf, und es verwendet keinen Code, der für Android geeignet ist. Und Sie werden sich schnell darüber im Klaren sein, dass diese Art von Trick nicht bedeutet, dass Ihre App nicht dem MVVM-Prinzip folgt (genauso wie Code hinter WPF). Code dahinter bedeutet nicht automatisch Verletzung von MVVM. –