Введение

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

Одной из обсуждаемых тем стало: «Следует ли диалог отображаться через навигацию и сохраняться как часть истории пользовательской навигации?» Мой ответ: «Это зависит от того, что именно мы подразумеваем под диалогом».

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

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

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

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

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

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

Не следует путать диалоги с экранами, которые просто не занимают весь дисплей устройства. Например, распространённый подход — показывать диалог во весь экран на смартфонах, тогда как на планшетах его отображают по центру, занимая лишь часть дисплея. При этом экран на планшете не становится диалогом, даже если визуально напоминает его. В Material Design отображение во весь экран на телефоне называется “полноэкранный диалог”.

Полноэкранный диалог на смартфоне и модальный диалог на планшете
Полноэкранный диалог на смартфоне и обычный на планшете
image.png
Диалог выбора в виде Bottom Sheet

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

Screenshot 2024-10-23 at 16.23.49.png
Side Sheet - версия Bottom Sheet для больших экранов
Контекстное меню в Android
Контекстное меню в Android

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

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

Четкого разделения по месту использования диалогов нет, но их можно классифицировать по влиянию на взаимодействие с интерфейсом — на модальные и немодальные.

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

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

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

Немодальные диалоги позволяют пользователю продолжать работу с приложением, поскольку не требуют немедленного взаимодействия. К этой категории относятся такие элементы, как Подсказки или Уведомления, часто реализованные в виде баннеров или Snackbar. Они отображаются ненавязчиво, предоставляя информацию или дополнительные опции, но не блокируют основной интерфейс и не прерывают рабочий процесс пользователя.

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

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

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

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

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

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

В итоге я для себя сформулировал несколько правил, касающихся экранов в навигации:

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

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

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

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

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

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

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

Комментарии (2)


  1. buratino
    04.11.2024 21:22

    Должен ли быть диалог управляться из решения для навигации?

    тут или "быть" лишнее или какая другая мысль недопроклюнулась


    1. kirich1409 Автор
      04.11.2024 21:22

      Поправил, спасибо