Более простой способ создания нестандартных размеров

Введение

Создание мобильного приложения, реагирующего на размер экрана и эстетически привлекательного, имеет решающее значение в эту современную эпоху. Один и тот же дизайн для мобильных устройств и планшетов больше не будет работать. Новые устройства, такие как Google-Nest, обучающее устройство Byjus и т. д., поставляются с настраиваемыми версиями Android для разных размеров экрана. Больше, чем когда-либо, нам нужно создавать приложения, которые можно масштабировать под разные размеры экрана.

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

Например, рассмотрим приложение чата на мобильных устройствах. Будет более эффективно, если мы покажем список предыдущих чатов на одном экране, а сам чат на другом экране. Но когда дело доходит до более крупных устройств, пользовательский опыт будет поднят на новый уровень, если мы покажем их рядом друг с другом, что известно как макет с двумя панелями. Предыдущий список чатов будет отображаться слева, а сведения о чате — справа.

Технические аспекты

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

Следующая сложность заключается в использовании двух фрагментов в одном макете. Для этого мы должны использовать SlidingPaneLayout. SlidingPaneLayout будет корнем фрагмента списка. До SlidingPaneLayout должно быть двое детей:

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

Преимущество SlidingPaneLayout заключается в том, что он использует ширину двух панелей, чтобы решить, показывать ли панели рядом или перекрывать их. Например, если минимальный размер левой и правой панорамы должен быть 250dp и 400dp соответственно, то бок о бок появляется только тогда, когда общий размер экрана равен или превышает 650dp.

Хватит теории. Давайте начнем.

SlidingPaneLayout Конфигурация

Начнем с XML-конфигурации родительского фрагмента, которая содержит корневой макет SlidingPaneLayout с двумя дочерними элементами:

  1. Recyclerview для представления списка элементов.
  2. FragmentContainerView, чтобы раздуть фрагменты деталей или навигационный график по вашему выбору.

Взгляните на код:

Мы можем раздуть этот XML в корень или фрагмент списка, где вы можете получить список из источника данных и опубликовать его через recyclerview.

Функциональность правого панорамирования

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

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

Вариант использования одного фрагмента

Давайте начнем с создания функции с именем openDetails, которая принимает один параметр, ничего, кроме класса данных выбранного элемента. Взгляните на код:

Здесь мы поддерживаем транзакции фрагментов без использования каких-либо компонентов навигации, и это нормально, поскольку мы имеем дело с более простым вариантом использования. Пожалуйста, помните, что мы используем транзакции фрагментов replace и не используем какие-либо функциональные возможности addToBackStack(), чтобы избежать преднамеренного создания backstack.

Вариант использования NavGraph

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

Изменения XML:

<androidx.fragment.app.FragmentContainerView
        android:id="@+id/two_pane_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        <!-- The navigation graph for your detail pane.-->
        app:navGraph="@navigation/details_nav_graph" />

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

Настройте систему Back Click с помощью SlidingPaneLayout

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

Ответственность за обратную навигацию лежит на разработчиках. Мы можем сделать это, связав OnBackPressedCallback с текущим состоянием панели. Начнем с создания клиента OnBackPressedCallback. Взгляните на код:

Теперь нам нужно добавить наш пользовательский обратный вызов обратного нажатия в OnBackPressedDispatcher, используя addCallback(). Взгляните на код:

Еще одна вещь, которую нам нужно позаботиться о скользящем панорамировании на мобильных устройствах, — это заблокировать скользящее поведение, потому что это другой экран с точки зрения UX на мобильных устройствах. Это полностью зависит от вашего варианта использования.

binding.slidingPaneLayout.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED

Бонус



На данный момент - все. Надеюсь, вы узнали что-то полезное. Спасибо за прочтение!