Как управлять ListView с шаблоном MVP для Android

В настоящее время я разрабатываю приложение для Android с использованием шаблона MVP.

Когда я пытаюсь разработать Activity, я должен использовать ListView. Поэтому я использую Adapter для ListView. Но я слышал, что Adapter похож на Presenter на шаблон MVP.

Я думаю, если Apdater будет знаком с Presenter, тогда я должен сделать Presenter для обновления ListView вместо Adapter.

В этой ситуации, как разработать ListView? Просто используйте Adapter и продолжайте использовать шаблон MVP?

Спасибо за ваше чтение.

Ответы

Ответ 1

Да, адаптер должен быть компонентом P в шаблоне MVP. Фактически ListViews в значительной степени написаны как MVP - функция getView() должна устанавливать все значения вида каждый раз при вызове, что почти определение того, что должен делать ведущий. Хотя это также легко использовать в способе типа MVC - просто есть функции вызова getView в представлении, которые передают ему модель и делают это в представлениях. Так что в любом случае все будет работать, просто выберите ваши предпочтения.

Если вы используете модель MVP со сложными строками списка, мне нравится делать строки настраиваемым составным представлением и помещать на нем больше описательных имен функций, а не переходить listRow.findViewById(R.id.textView).setText(filename) Я пойду listRow.setFilename(имя файла), и пусть представление узнает, что с этим делать. Этот вид немного размывает границы MVP и MVC, но я считаю, что это хороший баланс читаемости вашего адаптера и избежание некоторой неловкости, которую иногда приносит простой MVC.

Ответ 2

Адаптер является частью представления. Фактически, все зависимости от Android должны быть частью представления. Чтобы изолировать адаптер от вашей модели и вашего презентатора, это сложная задача. Для этой цели я выпустил библиотеку под названием PaperKnife.

Вы можете использовать PaperKnife для отсоединения адаптера от модели и уровня презентатора. Выполните следующие шаги:

  • Провести анализ уровня модели с помощью интерфейса CellElement. Ваш уровень просмотра не обязательно должен знать вашу модель.

  • Создайте класс для предоставления информации для вашего представления строки. Вы можете использовать своего ведущего. Реализует класс CellDataProvider и создает методы для предоставления всей информации. Аннотирование методов вашего провайдера с помощью @DataSource("DataId") для выполнения сопоставления. Ваши методы данных получают экземпляр вашего класса модели. Например:

    public class SamplePresenterImpl implements SamplePresenter, CellDataProvider {
        @DataSource("Title")
        public String getTitle(Item item) {
            return item.getTitle();
        }
        // etc.
    }
    
  • Создайте ViewHolder в своем адаптере и реализуйте интерфейс CellViewHolder. Создайте методы управления представлениями и используйте DataTarget("DataId")

    static class ViewHolder extends CellViewHolder {
        @DataTarget("Title")
        public String setTitle(String title) {
            mTextViewTitle.setText(title);
        }
    }
    
  • Выполните отображение в вашем адаптере getView:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // etc.
        PaperKnife.map(mList.get(position))
                        .dataProvider(mCellDataProvider)
                        .into(viewHolder);
        return convertView;
    }
    

Таким образом, ваш уровень представления просто знает интерфейс CellElement, и ваш ведущий несет ответственность за предоставление данных вашему адаптеру.

Ответ 3

Если в этой активности есть только список, тогда нет необходимости писать отдельный презентатор, потому что Adapter фактически работает как Presenter для ListView. Но если у вас есть другие компоненты пользовательского интерфейса, чем ListView, которые необходимо обновить, вам нужно будет написать отдельный презентатор для этих компонентов пользовательского интерфейса.

Ответ 4

Приложения Android в основном построены вокруг Model-View-Controller (MVC) - MVP звучит как одно и то же, хотя я и не слышал этого термина раньше. Действия выполняют роль Контроллера, XML-представления - это просто (хотя вы можете создавать их программно в Activity - это проще и проще сделать это в XML), и модель, которую вы пишете сами. Так что да, эта модель вполне практична.

Возможная причина, по которой вы, возможно, не слышали много об этой модели дизайна, заключается в том, что фреймворк Android заставляет вас отделить представление. Поскольку приложение на мобильных устройствах имеет тенденцию быть небольшим, люди не склонны использовать полнофункциональный MVC; они имеют тенденцию к представлению и уровням действия, в которых слой действия выполняет большую часть модели (малого) задания.

Если вы пишете кросс-платформенное приложение, вам может потребоваться четырехслойный подход: просмотр, действие, бизнес-логика и модель. Уровни представления и действия будут специфичными для платформы, а бизнес-логика и модель не изменятся. В принципе, вы разделяете презентацию и взаимодействие пользователя с уровнем Action, который вызывает уровень Business Logic для выполнения действий, которые пользователь хочет.