Введение
Недавно я начал разработку собственной библиотеки для UI-навигации на Kotlin Multiplatform. Создать решение, которое бы удовлетворяло все творческие задумки дизайнеров и продуктовых менеджеров, оказалось задачей непростой. Поэтому я решил делиться концепцией и функциональными возможностями библиотеки еще на стадии разработки, чтобы получать обратную связь от коллег-разработчиков.
Одной из обсуждаемых тем стало: «Следует ли диалог отображаться через навигацию и сохраняться как часть истории пользовательской навигации?» Мой ответ: «Это зависит от того, что именно мы подразумеваем под диалогом».
Меня зовут Кирилл Розов, и в этой статье я расскажу, что я понимаю под диалогом в Material Design и как, на мой взгляд, стоит работать с ними в системе навигации.
Если вам интересно следить за самыми последними новостями Android разработки и получать подборку интересных статей по этой тематике, тогда вам стоит подписаться на Телеграм-канал Android Broadcast и мой YouTube канал "Android Broadcast"
Что такое диалог
Диалог в пользовательском интерфейсе (UI — User Interface) — это всплывающее окно, панель или экран, который временно отображается поверх основного содержимого приложения или сайта.

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


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


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

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

Немодальные диалоги позволяют пользователю продолжать работу с приложением, поскольку не требуют немедленного взаимодействия. К этой категории относятся такие элементы, как Подсказки или Уведомления, часто реализованные в виде баннеров или 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 навигации. Делитесь им в комментариях и давайте искать истину вместе!