Диалог — часть навигации или нет?

Введение

Не так давно я начал разработку собственной библиотеки для навигации в клиентских приложениях на Kotlin Multiplatform. Сделать такое решение подходящим под фанатзию каждого дизайнера и менеджера продукта сложно. Поэтому я начал рассказывать про библиотеку и её концепции на стадии разработки, чтобы понять как это может подойти разработчикам, особенно тем кто уже имеют большую кодовую базу. Одной из спорных тем, которая у нас появилась в рамках обсуждения: «Должен ли диалог показываться через навигацию и хранится как часть истории навигации пользователя?» Мой ответ: «Зависит от того что понимаем под диалогом и цель его показа».

Меня зовут Кирилл Розов и в этой статье я расскажу вам что понимает под диалогом в Material Design и свой взгляд как работать с диалогами в навигации

Если вам интересно следить за самыми последними новостями Android разработки и получать подборку интересных статей по этой тематике, тогда вам стоит подписаться на Телеграм-канал Android Broadcast и мой YouTube канал «Android Broadcast»

Что такое диалог

Диалог в пользовательском интерфейсе (UI — User Interface) — это всплывающее окно, панель или экран, который временно отображается поверх основного содержимого приложения или сайта.

image.png

Диалог выбора даты

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

Не стоит путать диалоги с окнами, которые не занимают весь экран. Например, частым приемом является показ диалога на всю площадь экрана на смартфонах, а на планшете используется режим показа в окне. Экран на планшете от этого не становится Диалогом, но имеет визуальный стиль схожий с ним, хотя Material Design называет такой случай «Полноэкранный Диалог»

Полноэкранный диалог на смартфоне и модальный диалог на планшете

Полноэкранный диалог на смартфоне и обычный на планшете

image.png

Диалог выбора в виде Bottom Sheet

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

Screenshot 2024-10-23 at 16.23.49.png

Side Sheet — версия Bottom Sheet для больших экранов

Контекстное меню в Android

Контекстное меню в Android

В целом то, как что-то представляется диалогом или нет, мне показалось настолько условным, что даже контекстное меню можно отнести к диалогам.

Модальность диалога

Явное разделения по месту использования диалогов нет, но их можно разделить по влиянию на возможность взаимодействия c UI на модальные и немодальные.

Пример диалога с подтверждением действия

Пример диалога с подтверждением действия

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

Пример немодального диалога

Пример немодального диалога

Немодальные диалоги позволяют продолжать работать с приложением т.к. не требуют немедленного взаимодействия с ним. Сюда относятся подсказки или уведомления. Зачастую они представлены как Баннер или Snackbar.

Диалог в навигации: быть или не быть

Под навигацией пользователя в UI я понимаю переход по Экранам приложения. История навигации возвращается после восстановления приложения. Потеря любого из такого элемента навигации критичная для пользователя.

Если рассмотреть библиотеку навигации Jetpack Navigation для Compose, то прямо в документации метода dialog () говорится:

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

Показ Экрана в виде диалог коде Jetpack Navigation хоть и выделен функций, но это лишь визуальная обертка в Dialog и по сути имеет мало разницы с показом обычного Экрана

// Пример использования Jetpack Navigation для показа Composable
// во всплывающем окне в стиле диалога
NavHost(
  navController = navController,
  startDestination = startDestination,
  modifier = modifier
) {
    dialog{
      // Показываем Composable функцию, которую обернут в диалог
    }
    composable {
      // Показ Composable функции на всём доступном пространстве
    }
  }

В итоге я для себя принял ряд правил касательно экранов в навигации:

  • Все контекстные элементы UI не относятся к навигации, например Контекстное Меню

  • Все немодальные диалоги НЕ относятся к навигации приложения, так как это лишь визуальные инструменты уведомлений. Они могут относится к состоянию Экрана или быть частью глобального состояния

  • Диалог подтверждения и выбора не является частью навигации, так как считается визуальным инструментом предотвращения случайного действия и привязан к контексту. Могут быть частью состояния Экрана

  • Экран приложения, показываемый в стиле диалога, является частью навигации. Здесь диалог лишь накладываемый стиль. Такой Экран на отдельных устройствах может занимать всё доступное пространство

  • Контент приложения, который показывается в стиле диалога, считается частью навигации, потому что сохраняется при переходах по экранам и помещается в back stack

В своём решение навигации выделять работу с диалогами я не вижу смысла, так это лишь визуальный стиль Экрана в состоянии навигации, за который должна отвечать UI часть навигации.

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

© Habrahabr.ru