J'ai une activité avec deux fragments.
L'activité (MainActivity
) récupère les données d'une API météo ouverte. J'ai implémenté MVP pour cela dans lequel: Model
contient tous les objets de réponse de l'APIView
est le Activity
Presenter
contient MainPresenter
, MainPresenterImpl
, MainView
, GetDataInteractor
et GetDataInteractorImpl
.
Ainsi, l'activité obtient les données du service Web. Les deux fragments afficheront les données des données récupérées dans l'activité.
Quelle est la meilleure pratique d'utilisation de MVP dans cette situation? Je sais comment transmettre des données entre les fragments <-> activité via l'interface/rappels, ma question est ce comportement change-t-il lors de la mise en œuvre de MVP?
L'activité/les fragments doivent être considérés uniquement comme la vue dans le modèle MVP. Cela signifie qu'ils doivent simplement afficher les données et recevoir les interactions des utilisateurs. Il est correct de communiquer l'activité et les fragments via l'interface/les rappels.
Mais, ce n'est pas une responsabilité d'activité/fragment d'appeler les services API.
Le présentateur devrait être responsable d'appeler les services de l'API.
Ainsi, le présentateur devrait exposer une méthode comme loadXXX
, en interne, il ferait l'appel au service. Lorsque la réponse est reçue, le présentateur doit appeler view.showXXX
Avec les résultats du service. L'activité/le fragment doit appeler cette méthode loadXXX
et implémenter la showXXX
.
Habituellement, le présentateur est créé ou injecté dans l'activité/le fragment. L'activité/le fragment doit implémenter une interface exposée par le présentateur, et le présentateur détient une référence faible de cette interface, afin qu'il puisse rappeler.
Lorsque l'utilisateur interagit avec l'écran, par exemple, un onClick
sur un bouton, l'activité/le fragment appelle la méthode correspondante dans le présentateur, par ex. presenter.loadUserDetails()
le présentateur indique à la vue de s'afficher comme chargement, par exemple view.showAsLoading()
car il doit faire son travail: peut-être valider quelque chose ou charger des données à partir d'un service api et enfin rappeler avec les résultats à la vue, par ex. view.showUserDetails(userDetails)
.
Pour résumer, un exemple, en code des différentes parties de MVP:
Activité/Fragment représente juste la vue de 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) {
...
}
}
Modèle:
public class UserDetails {
...
}
Présentateur:
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);
}
}