2015-12-13 12 views
33

Ich habe eine Aktivität mit zwei Fragmenten drin.MVP für Aktivität mit mehreren Fragmenten

Die Aktivität (MainActivity) ruft Daten von einer offenen Wetter-API ab. Ich habe MVP für diesen, in denen implementiert: Model enthält alle Response-Objekte aus der API
View die Activity
Presenter ist enthält MainPresenter, MainPresenterImpl, MainView, GetDataInteractor und GetDataInteractorImpl.

So erhält die Aktivität die Daten vom Web-Service. Beide Fragmente zeigen Daten aus den in der Aktivität abgerufenen Daten an.

Was ist die beste Vorgehensweise bei der Verwendung von MVP in dieser Situation? Ich weiß, wie Daten zwischen Fragmenten übergeben werden < -> Aktivität über Schnittstelle/Callbacks, ist meine Frage, ändert sich dieses Verhalten bei der Implementierung von MVP?

+1

Nur ein Gedanke: Ich würde Fragmente als Ansichten (in Bezug auf MVP) betrachten, daher frage ich mich, ob es seltsam wäre, wenn ein Moderator mehrere Ansichten referenziert (oder vielmehr: ihre Schnittstellenrückrufe), um unterschiedliche Daten in der am besten geeigneten Ansicht anzuzeigen dafür? Ich würde denken, dass ein Moderator entscheiden muss, welche Ansicht welche Daten anzeigt. Anscheinend mehrere Moderatoren für eine Ansicht ist ein gültiger Ansatz, vielleicht funktioniert auch andersherum: http://StackOverflow.com/a/2068/1041533 – AgentKnopf

+2

@AgentKnopf eigentlich, wie hier angegeben http://programmers.stackexchange.com/a/261351/206366 in MVP ist jeder Moderator für die Präsentation einer Ansicht verantwortlich. Der Präsentator kann nur dann mehrere Ansichten darstellen, wenn die verschiedenen Ansichten lediglich unterschiedliche Implementierungen einer einzelnen Ansichtsschnittstelle darstellen, die an den Präsentator gebunden ist. – Ari

+0

@Ari danke für das Follow-up - das macht in der Tat Sinn! – AgentKnopf

Antwort

12

Die Aktivität/Fragmente sollten nur als Ansicht im MVP-Modell betrachtet werden. Dies bedeutet, dass sie nur Daten anzeigen und Benutzerinteraktionen erhalten sollten. Es ist in Ordnung, Aktivität und Fragmente über Schnittstelle/Callbacks zu kommunizieren.

Es ist jedoch keine Aktivität/Fragment-Verantwortung, die API-Dienste aufzurufen.

Der Präsentator sollte dafür verantwortlich sein, die API-Dienste aufzurufen.

So sollte der Moderator eine Methode wie loadXXX offen legen, intern würde es den Aufruf an den Dienst machen. Wenn die Antwort empfangen wird, sollte der Präsentator view.showXXX mit den Ergebnissen des Dienstes aufrufen. Die Aktivität/das Fragment sollte diese loadXXX Methode aufrufen und die showXXX implementieren.

Normalerweise wird der Präsentator erstellt oder in die Aktivität/das Fragment eingefügt. Die Aktivität/das Fragment muss eine Schnittstelle implementieren, die vom Präsentator bereitgestellt wird, und der Präsentator enthält eine schwache Referenz dieser Schnittstelle, sodass ein Rückruf möglich ist.

Wenn der Benutzer mit dem Bildschirm interagiert, z. B. onClick auf einer Schaltfläche, ruft die Aktivität/das Fragment die entsprechende Methode im Presenter auf, z. presenter.loadUserDetails() Der Präsentator teilt der Ansicht mit, dass er als Laden angezeigt werden soll, z. view.showAsLoading(), weil es seine Sachen machen muss: vielleicht etwas überprüfen oder Daten von einem API-Dienst laden und schließlich mit den Ergebnissen zu der Ansicht zurückrufen, z. view.showUserDetails(userDetails).

Zusammengefasst ein Beispiel, in Code der verschiedenen Teile von MVP:

public class MyActivity extends AppCompatActivity implements MyPresenter.View { 
    private MyPresenter mPresenter; 

    public onCreate() { 
     ... 
     mPresenter = new MyPresenter(this); // Or inject it and then set the view. 
    } 

    public void onClick(View v) { 
     mPresenter.loadXXX(param1, param2); 
    } 

    // MyPresenter.View methods 

    public void showAsLoading() { 
     ... 
    } 

    public void showUserDetails(UserDetails userDetails) { 
     ... 
    } 
} 

Modell:

public class UserDetails { 
    ... 
} 

Presenter

Aktivität/Fragment nur die Ansicht von MVP repräsentiert :

public class MyPresenter { 

    private WeakReference<MyPresenter.View> mWeakView; 

    public MyPresenter(MyPresenter.View view) { 
     mWeakView = new WeakReference(view); 
    } 

    public void loadXXX(String param1, String param2) { 
     MyPresenter.View view = mWeakView.get(); 
     if (view != null) { 
      view.showAsLoading(); 
      // Do stuff, e.g. make the Api call and finally call view.showUserDetails(userDetails); 
     } 
    } 

    interface View { 
     void showAsLoading(); 
     void showUserDetails(UserDetails userDetails); 
    } 

} 
+0

Herr, können Sie erklären, warum mWeakView eine WeakReference ist, aus welchen Gründen? –

+1

Dies verhindert, dass ein Verweis auf die Aktivität/das Fragment beibehalten wird. Der Präsentator stellt asynchrone Anforderungen an APIs. Wenn Sie die Aktivität zurück drücken oder beenden, während der Präsentator die Anfrage ausführt und keine WeakReference verwendet, behält der Präsentator den Aktivitäts-/Fragmentspeicher (alle Ansichten und Mitglieder dieser Aktivität/dieses Fragments werden beibehalten). Anstatt eine WeakReference zu verwenden, ist es auch üblich, eine Attach- und Detach-Methode im Presenter anzuzeigen. Nachdem Sie den Moderator instanziiert haben, sollten Sie die attach-Methode aufrufen und wenn die onDestroy-Funktion von activity/Fragment aufgerufen wird, sollten Sie detach aufrufen. – fernandospr

+0

Wenn Sie keine WeakReference- oder attach/dettach-Methode verwenden und Ihre Aktivität/Ihr Fragment zerstört wurde, bevor die Anfrage des Moderators beendet wurde, können Sie beim Beenden der Anfrage Probleme bekommen, da sie versuchen, etwas auf dem Zerstörten zu aktualisieren Aktivität/Fragment. – fernandospr

Verwandte Themen