Другой способ думать о вашем пользовательском интерфейсе в виде декларативных функций и последовательной архитектуры.

Мотивация: вы могли запускать такие приложения, как Netflix / Amazon Prime, где отдельный экран содержит множество просмотров, которые повторно используются во всем приложении. Например, рассмотрим приложение Amazon Prime Video.

Рассмотрим главный экран, , который содержит список Смотреть следующие фильмы, триллеры, Рекомендуемые фильмы и Последние фильмы, сложены один под другим. Все вышеперечисленное имеет один и тот же пользовательский интерфейс с разными наборами данных.

Рассмотрим экран фильма, который содержит обзор фильма, а под ним вы можете найти раздел Клиент также смотрел. Это тот же интерфейс, который использовался на главном экране . Таким образом, части представления повторно используются во всем приложении.

Проектирование экранов

Как бы вы разработали такие экраны?

Наивный способ

Один из способов создания вышеуказанных экранов - это жесткое кодирование представлений для каждого из экранов. Но мы сталкиваемся с проблемами.

Во-первых, наш уровень домена или представления не может иметь логики для изменения представлений. В конечном итоге мы меняем множество файлов, если просто хотим добавить что-то вроде актеров в пользовательский интерфейс экрана.

Во-вторых, проблема дублирования.

При использовании описанного выше подхода мы в конечном итоге дублируем код, чтобы отобразить список фильмов на главном экране и экране фильма. Как только вы слышите дублирование, мы переносим их в обычное место.

С помощью предлагаемой архитектуры (ниже) мы можем преодолеть вышеуказанные проблемы, разместив дублирующийся код в общем месте под названием UIComponents.

Что такое UIComponents?

Части пользовательского интерфейса, которые можно повторно использовать и которые являются автономными, называются UIComponents. Вы можете подключить их в любом месте приложения на любом из экранов, и все готово.

Что такое компонентная архитектура?

Здесь экран Activity состоит из набора повторно используемых UIComponents. Действие не несет ответственности за создание представлений в своем XML-файле. Скорее он включает только UIComponents.

В этой статье мы сосредоточимся только на рендеринге UIComponents на экране. Позже мы рассмотрим обработку взаимодействия компонентов UIComponents с внешним миром здесь.

Android Jetpack Compose

Jetpack Compose - это набор инструментов для проектирования, упрощающий разработку пользовательского интерфейса в Android. Он полностью декларативен, то есть вы описываете свой пользовательский интерфейс, вызывая серию функций, которые преобразуют данные в иерархию пользовательского интерфейса - определение.

В Jetpack Compose представления - это составляемые функции.

Вот как вы определяете представление в Jetpack Compose:

Компонентная архитектура в Jetpack Compose

Остальная часть статьи будет разделена на три части с некоторым кодом.

  1. Определение / построение UIComponents.
  2. Создание UIComponents нашим ViewModel путем предоставления данных, необходимых для UIComponent.
  3. Включение UIComponents в действие Jetpack Compose.

Взаимосвязь разных слоев приложения выглядит так. Позже мы будем импровизировать.

Для этой демонстрации мы создадим приложение со следующими экранами:

  1. Главный экран с популярными фильмами и фильмами с самым высоким рейтингом.
  2. Экран деталей фильма, с обзором фильмов, актерами / съемочной группой, рекомендованными и аналогичными фильмами.

1. Сборка UIComponents

Удобный псевдоним типа составной функции для составных представлений. (Помните? Представления - это составляемые функции.)

Интерфейс UIComponent должен быть реализован всеми компонентами UIComponent. Это базовая версия нашего UIComponent. Мы изменим это позже, когда начнем работать с взаимодействиями.

Чтобы лучше соответствовать нашей цели и лучше объяснять вещи, мы будем создавать MovieDetailScreen. Он имеет следующие компоненты UIComponents:

  • Обзор фильма (MovieOverviewUIComponent)
  • Актеры фильма (CastListUIComponent)
  • Съемочная группа (CrewListUIComponent)
  • Похожие фильмы (MovieListUIComponent)
  • Рекомендуемые фильмы (MovieListUIComponent)

Теперь мы создадим MovieListUIComponent, который можно использовать для рендеринга похожих фильмов и рекомендуемых фильмов на экране.

Давайте добавим две функции расширения для вертикальной и горизонтальной прокрутки.

Давайте построим MovieListUIComponent.

1. Дизайн MovieView (Составной). Это будет составная функция. Напоминание: представления - это функции в Jetpack Compose.

2. Затем мы создаем список фильмов с горизонтальной прокруткой - HMovieListView.kt . Мы будем использовать функцию расширения, которую мы создали ранее (HStack).

3. Теперь, когда View создан, мы можем создать MovieListUIComponent. Компонент получает свои данные (movieList) от ViewModel. Эти данные используются HMovieListView.

Наша первая часть закончена, мы создали UIComponents. Вы можете получить полный код на GitHub.

2. Создание уровня презентации

Примечание. Приведенный ниже код на самом деле проще, чем вы видите здесь, когда смотрите на полный ViewModel.

1. Давайте создадим один класс данных для хранения данных для пользовательского интерфейса, MovieDetailPageUiModel. Это неизменный (все vals). Мы используем редукторы для обновления состояния. Он содержит все UIComponents, необходимые для представления. Посмотрите ниже.

2. В ViewModel это будет MutableLiveData. Он содержит полное состояние этого конкретного действия Jetpack Compose.

3. ViewModel является держателем данных и отвечает за создание UIComponents. Как указывалось ранее, ViewModel извлекает данные из нескольких источников данных (API или постоянство), которые необходимы для создания компонентов.

Когда мы получаем данные, мы создаем наши UIComponents и обновляем (уменьшаем) наш mutableLiveData.

Например: когда мы получаем рекомендованные фильмы, мы создаем MovieListUIComponent и обновляем значение recommendedMoviesListUIComponent в movieDetailPageUiModel.

Это касается всех значений в movieDetailPageUiModel. Взгляните на код, который дает понять:

Вот и все! Вы можете посмотреть нашу полную ViewModel на GitHub.

3. Создание последней части - вид (упражнение "Создание реактивного ранца")

Цель: действие должно отображать все компоненты UIC в вертикальном порядке, как RecyclerView. В настоящее время мы имитируем RecyclerView, используя VStack. Но вам следует подумать об использовании AdapterList.

  1. В нашем MovieDetailPageView у нас есть вертикальный скроллер, который отображает все компоненты UIC по вертикали. View наблюдает за изменением данных и обновляется.

Посмотрите, как мы перебираем список UIComponents и визуализируем каждый из них вертикально. (Подобно нескольким типам представлений в RecyclerView, где каждый UIComponent является отдельным типом представления.)

2. Продолжая вышеупомянутый пункт. В HomePageUIModel потребуется небольшое изменение. Мы добавляем функцию (components()), которая возвращает список UIComponents.

3. Соблюдайте HomePageUIModel (pageData в нашем ViewModel) и обновляйте представление всякий раз, когда оно изменяется.

Вы можете посмотреть код на GitHub.

Пользовательский интерфейс, управляемый сервером. Кроме того, мы можем управлять пользовательским интерфейсом через ответ API. Вместо того, чтобы создавать UIComponents в ViewModel, мы перемещаем его в обычное место, как показано ниже. UIComponents создаются на основе ответа сервера.

Заключение

После этого мы можем переместить UIComponents в отдельную библиотеку, которую можно будет повторно использовать в разных приложениях.

В настоящее время мы только разместили на экране UIComponents. В следующей статье рассматривается взаимодействие с событиями щелчка UIComponents👇🏼.