Это будет длинный пост о том, как структурировать проект MVP, прежде чем приступить к решению вашей проблемы в самом конце моего ответа.
Я просто сообщаю о структуре MVP здесь как структурировать проект MVP из моего собственного ответа.
Я часто помещаю код бизнес-логики на уровень модели (не путайте с моделью в базе данных). Я часто переименовываю как XManager
, чтобы избежать путаницы (например, ProductManager
, MediaManager
...), поэтому класс докладчика просто используется для сохранения рабочего процесса.
Практическим правилом является отсутствие или, по крайней мере, ограничение импорта пакета Android в классе докладчика. Эта передовая практика помогает вам легче тестировать класс Presenter, потому что Presenter теперь является просто классом Java, поэтому нам не нужна среда Android для тестирования этих вещей.
Например, вот мой рабочий процесс mvp.
Класс просмотра: это место, где вы храните все свои представления, такие как кнопка, текстовое представление... и устанавливаете все слушатели для этих компонентов представления на этом уровне. Также в этом представлении вы позже определяете класс Listener для реализации Presenter. Компоненты вашего представления будут вызывать методы этого класса прослушивателя.
class ViewImpl implements View {
Button playButton;
ViewListener listener;
public ViewImpl(ViewListener listener) {
// find all view
this.listener = listener;
playButton.setOnClickListener(new View.OnClickListener() {
listener.playSong();
});
}
public interface ViewListener {
playSong();
}
}
Класс Presenter: здесь вы сохраняете представление и модель для последующего вызова. Также класс Presenter будет реализовывать интерфейс ViewListener, определенный выше. Суть презентера в управлении логикой рабочего процесса.
class PresenterImpl extends Presenter implements ViewListener {
private View view;
private MediaManager mediaManager;
public PresenterImpl(View, MediaManager manager) {
this.view = view;
this.manager = manager;
}
@Override
public void playSong() {
mediaManager.playMedia();
}
}
Класс менеджера: здесь представлен основной код бизнес-логики. Возможно, у одного презентера будет много менеджеров (зависит от сложности представления). Часто мы получаем класс Context
через какую-то среду внедрения, такую как Dagger
.
Class MediaManagerImpl extends MediaManager {
// using Dagger for injection context if you want
@Inject
private Context context;
private MediaPlayer mediaPlayer;
// dagger solution
public MediaPlayerManagerImpl() {
this.mediaPlayer = new MediaPlayer(context);
}
// no dagger solution
public MediaPlayerManagerImpl(Context context) {
this.context = context;
this.mediaPlayer = new MediaPlayer(context);
}
public void playMedia() {
mediaPlayer.play();
}
public void stopMedia() {
mediaPlayer.stop();
}
}
Наконец: объедините эти вещи в Действия, Фрагменты... Здесь вы инициализируете представление, управление и назначаете все докладчику.
public class MyActivity extends Activity {
Presenter presenter;
@Override
public void onCreate() {
super.onCreate();
IView view = new ViewImpl();
MediaManager manager = new MediaManagerImpl(this.getApplicationContext());
// or this. if you use Dagger
MediaManager manager = new MediaManagerImpl();
presenter = new PresenterImpl(view, manager);
}
@Override
public void onStop() {
super.onStop();
presenter.onStop();
}
}
Вы видите, что каждый презентер, модель, представление обёрнуты одним интерфейсом. Эти компоненты будут вызываться через интерфейс. Такой дизайн сделает ваш код более надежным и удобным для последующего изменения.
Короче говоря, в вашей ситуации я предлагаю такую конструкцию:
class ViewImpl implements View {
Button button;
TextView textView;
ViewListener listener;
public ViewImpl(ViewListener listener) {
// find all view
this.listener = listener;
button.setOnClickListener(new View.OnClickListener() {
textView.setText(resource_id);
});
}
}
В случае, если логическое представление сложное, например, некоторые условия для установки значения. Поэтому я добавлю логику в DataManager
для получения обратно текста. Например:
class Presenter {
public void setText() {
view.setText(dataManager.getProductName());
}
}
class DataManager {
public String getProductName() {
if (some_internal_state == 1) return getResources().getString(R.string.value1);
if (some_internal_state == 2) return getResources().getString(R.string.value2);
}
}
Таким образом, вы никогда не помещаете вещи, связанные с Android, в класс докладчика. Вы должны переместить это в класс View
или DataManager
в зависимости от контекста.
Это очень длинный пост, в котором подробно рассказывается о MVP и о том, как решить вашу конкретную проблему. Надеюсь, это поможет :)
person
hqt
schedule
27.11.2016