Деятельность/фрагменты следует рассматривать как просто представление в модели MVP. Это означает, что они должны просто показывать данные и получать пользовательские взаимодействия. Вполне нормально передавать активность и фрагменты через интерфейс/обратные вызовы.
Но это не ответственность за действие/фрагмент, чтобы вызвать службы API.
Ведущий должен нести ответственность за вызов служб api.
Итак, ведущий должен выставить такой метод, как loadXXX
, внутренне он сделает звонок к сервису. Когда ответ получен, ведущий должен позвонить view.showXXX
с результатами этой услуги. Действие/фрагмент должен вызвать этот метод loadXXX
и реализовать showXXX
.
Обычно презентатор создается или вводится в действие/фрагмент. Действие/фрагмент должен реализовывать интерфейс, открытый презентатором, а ведущий хранит слабую ссылку на этот интерфейс, чтобы он мог обратный вызов.
Когда пользователь взаимодействует с экраном, например, onClick
на кнопке, действие/фрагмент вызывает соответствующий метод в презентаторе, например. presenter.loadUserDetails()
Ведущий сообщает, что представление отображается как загрузка, например. view.showAsLoading()
, потому что он должен делать свои вещи: возможно, что-то подтвердить или загрузить данные из службы api и, наконец, обратный вызов с результатами в представление, например. view.showUserDetails(userDetails)
.
Резюмируя, пример, в коде различных частей MVP:
Деятельность/Фрагмент представляет собой лишь Вид 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) {
...
}
}
Модель:
public class UserDetails {
...
}
Presenter :
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);
}
}
Только что подумал: я бы рассмотрел фрагменты, которые будут считаться как Views (в отношении MVP), поэтому я задаюсь вопросом, было бы странно иметь одну презентацию, ссылающуюся на несколько представлений (точнее, на их обратные вызовы) для отображения разных данных в наиболее подходящем представлении для этого? Я думаю, что ведущий должен решить/направить, какое представление отображает данные? P.s. По-видимому, несколько презентаторов для одного представления - это действительный подход, поэтому, возможно, работает и наоборот: http://stackoverflow.com/a/2068/1041533 – AgentKnopf
@AgentKnopf на самом деле, как указано здесь http://programmers.stackexchange.com/a/261351/206366 в MVP каждый ведущий несет ответственность за представление одного представления. Единственный способ, которым презентатор может представить несколько представлений, состоит в том, что разные представления представляют собой просто разные реализации одного интерфейса представления, который связывается с ведущим. – Ari
@ Ари благодарю вас за продолжение - это действительно имеет смысл! – AgentKnopf