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);
}
}
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
@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
@Ari danke für das Follow-up - das macht in der Tat Sinn! – AgentKnopf