Navigation Compose: что это, архитектура и работа в разработке

Автор: IT Sectr Опубликовано: 2026-06-29 Время чтения: 8 мин

Navigation Compose — это библиотека Jetpack для декларативной навигации внутри Android-приложений, построенных на Jetpack Compose. Вместо FragmentManager или Intent-based навигации Navigation Compose предлагает единый граф маршрутов, управляемый через NavController и NavHost. По данным Google I/O (2025), Navigation Compose — рекомендуемый способ навигации для Compose-приложений, используемый более чем в 70% новых проектов. Библиотека поддерживает передачу типизированных аргументов, глубокие ссылки, анимацию переходов и интеграцию с ViewModel через SavedStateHandle.

Главное

  • Navigation Compose — библиотека Jetpack для декларативной навигации в Compose с единым графом маршрутов
  • NavController — центральный контроллер, управляющий стеком навигации и состоянием back stack
  • NavHost — контейнер, определяющий граф маршрутов через composable-функции с route
  • Аргументы передаются через NavType и SavedStateHandle с поддержкой типизированных параметров
  • Deep Links — навигация через внешние URL с автоматическим разбором аргументов из URI

Что такое Navigation Compose?

Navigation Compose — это библиотека из состава Jetpack, предоставляющая навигационный фреймворк для Compose-приложений. Библиотека базируется на тех же принципах, что и Navigation Component для View-системы, но адаптирована под декларативную природу Compose: вместо FragmentTransaction используются composable-функции, а граф навигации строится через Kotlin DSL.

Ключевое отличие Navigation Compose от классической навигации — отсутствие FragmentManager. Каждый экран — это composable-функция, которая рендерится в NavHost при совпадении маршрута. Back stack хранит не Fragment, а запись с route, аргументами и состоянием. Это упрощает архитектуру и исключает lifecycle-конфликты, характерные для Fragment-навигации.

По данным Google (2025), Navigation Compose прошёл путь от experimental до stable и входит в состав Jetpack с версии 2.8.0. Библиотека поддерживает Material3, Type-Safe Navigation (через Kotlin Serialization), вложенные графы и модуляризацию. Единственное ограничение — библиотека не поддерживает multi-back stack для BottomNavigation без ручной настройки, хотя Google работает над этим.

Архитектура Navigation Compose строится вокруг трёх сущностей: NavController (управление стеком), NavHost (контейнер графа) и NavDestination (отдельный маршрут с composable). Взаимодействие между ними декларативное: разработчик описывает маршруты и аргументы, а библиотека обрабатывает состояния загрузки, preserve и restore.

NavController — центральный элемент Navigation Compose, управляющий навигационным стеком. Создаётся через rememberNavController() и передаётся в NavHost. NavController хранит back stack, текущую точку входа и поддерживает отложенные действия (deeplink после инициализации графа).

kotlin
@Composable
fun AppNavigation() {
    val navController = rememberNavController()
    NavHost(navController = navController, startDestination = "home") {
        composable("home") { HomeScreen(navController) }
        composable("profile/{userId}") { backStackEntry ->
            ProfileScreen(
                userId = backStackEntry.arguments?.getString("userId") ?: ""
            )
        }
    }
}

Основные методы NavController: navigate(route) — переход по маршруту, popBackStack() — возврат на предыдущий экран, navigateAndClear(route) — переход с очисткой стека. NavOptions задают поведение: launchSingleTop предотвращает дублирование, popUpTo очищает стек до указанного маршрута, restoreState восстанавливает предыдущее состояние.

Для доступа к NavController из глубоко вложенных composable-функций используйте NavHostController через CompositionLocal. LocalNavController предоставляется в ScopedNavController внутри NavHost. Вне NavHost (например, в BottomNavigation) контроллер передаётся через параметры или ViewModel.

NavHost — это composable-контейнер, который связывает NavController с графом маршрутов. Каждый маршрут объявляется через composable(route, arguments, deepLinks), где route — строка маршрута с опциональными плейсхолдерами {param}. При совпадении текущего маршрута с route NavHost рендерит соответствующий composable-блок.

Граф маршрутов строится иерархически: можно вкладывать графы через navigation() для группировки маршрутов внутри модуля. Вложенные графы имеют собственный startDestination и объединяются под общим route-префиксом. Это позволяет организовать модульную архитектуру, где каждый feature-модуль регистрирует свой подграф.

kotlin
NavHost(
    navController = navController,
    startDestination = "main"
) {
    composable("main") { MainScreen(navController) }
    navigation(
        route = "auth",
        startDestination = "auth/login"
    ) {
        composable("auth/login") { LoginScreen(navController) }
        composable("auth/register") { RegisterScreen(navController) }
    }
}

NavHost автоматически обрабатывает системную кнопку Back (back press) через LocalBackDispatcher. В Material3 Scaffold по умолчанию подхватывает NavController для корректной работы BottomNavigation. NavHost пересоздаёт composable при изменении маршрута, но сохраняет состояние через rememberSaveable для полей ввода и скролла.

Передача аргументов между экранами

Navigation Compose поддерживает передачу типизированных аргументов между экранами через маршрутные параметры и NavType. Параметры задаются в route как {paramName} с указанием типа через arguments в composable(). NavType поддерживает String, Int, Long, Float, Boolean, Parcelable и Serializable.

Тип аргументаNavTypeПример route
StringNavType.StringType"profile/{name}"
IntNavType.IntType"item/{id}"
BooleanNavType.BoolType"settings?enabled={flag}"
ParcelableNavType.ParcelableType"details/{item}"
FloatNavType.FloatType"map?lat={lat}&lng={lng}"

Аргументы извлекаются из NavBackStackEntry через arguments?.getType(key). Для обязательных параметров используйте defaultValue, для опциональных — nullable. Поддержка Parcelable работает только с Kotlin Parcelize или библиотекой kotlinx.parcelize. Для complex-объектов рекомендуется передавать ID и загружать данные через ViewModel, а не сериализовать весь объект.

С версии Navigation 2.8.0 появилась Type-Safe Navigation с Kotlin Serialization: маршруты определяются как data-классы, а аргументы — как поля. Это заменяет строковые route на типизированные объекты и исключает ошибки в именах маршрутов. Для миграции требуется плагин Kotlin Serialization и зависимость navigation-compose-typesafe.

kotlin
@Serializable
/* sealed class Route */
sealed class ProfileRoute(val route: String) {
    data object Home : ProfileRoute("home")
    data class Profile(val userId: String) : ProfileRoute("profile/{userId}")
}

Deep Links — механизм навигации, позволяющий открыть определённый экран приложения через URL или intent-filter. В Navigation Compose deep links настраиваются через параметр deepLinks в composable() и обрабатываются автоматически при совпадении URI с шаблоном.

Deep Link задаётся как список UriPattern: "https://example.com/profile/{userId}". Параметры из URI автоматически маппятся в аргументы маршрута. NavController обрабатывает deep link при старте приложения (через intent) и в процессе работы (через implicit deep links). Для обработки pending deep links используется handleDeepLink() в NavController после инициализации графа.

По данным Google, deep links рекомендуется настраивать для: пушей (Firebase Dynamic Links), верификации email, шаринга контента и сквозной навигации из web-ссылок. Для Android 12+ используется Digital Asset Links для верификации авторитетности deep link. AndroidManifest.xml должен содержать intent-filter с autoVerify="true" для открытия ссылок без диалога.

kotlin
composable(
    route = "profile/{userId}",
    arguments = listOf(navArgument("userId") { type = NavType.StringType }),
    deepLinks = listOf(
        navDeepLink { uriPattern = "https://example.com/profile/{userId}" }
    )
) { backStackEntry ->
    ProfileScreen(userId = backStackEntry.arguments?.getString("userId") ?: "")
}

Ограничения deep links в Navigation Compose: библиотека не поддерживает deferred deep links — deep link обрабатывается только после того, как NavHost полностью построил граф. Если deep link пришёл до инициализации графа, его нужно отложить через intent?.data и обработать в LaunchedEffect. Для Firebase Dynamic Links используйте Firebase Dynamic Links SDK в связке с Navigation Compose.

Анимация переходов между экранами

Navigation Compose поддерживает анимацию переходов через параметры enterTransition, exitTransition, popEnterTransition и popExitTransition в composable(). Анимации реализуются через Compose Animation API: fadeIn, slideInHorizontally, expandIn и другие. По умолчанию анимация отключена — экраны заменяются мгновенно.

Типовые сценарии анимации: slideInHorizontally для навигации вперёд (экран заезжает справа), slideOutHorizontally для возврата (экран уезжает вправо). Для BottomNavigation чаще используется fade-анимация без слайда. Анимации задаются через NavHost и применяются ко всем composable, если не указаны индивидуальные.

kotlin
NavHost(
    navController = navController,
    startDestination = "home",
    enterTransition = { slideInHorizontally() + fadeIn() },
    exitTransition = { slideOutHorizontally() + fadeOut() },
    popEnterTransition = { fadeIn() },
    popExitTransition = { slideOutHorizontally() + fadeOut() }
) { /* composable */ }

Анимации можно переопределить для каждого composable индивидуально, передав анимационные параметры прямо в composable(). Важно: анимации не должны конфликтовать с системной анимацией back press. Для shared element transition требуется библиотека accompanist-navigation-animation или кастомная реализация через Modifier.graphicsLayer. По данным Android Developers (2025), 80% production-приложений используют slide горизонтальную анимацию для стандартной навигации.

Часто задаваемые вопросы

Чем Navigation Compose отличается от Navigation Component для View?

Navigation Compose работает без Fragment, используя composable-функции и Kotlin DSL для графа. Navigation Component (View) базируется на FragmentManager и XML-графах. Compose-версия проще, быстрее и не имеет жизненных циклов Fragment. Navigation Component для View подходит только для гибридных приложений.

Как передать сложный объект между экранами?

Рекомендуется передавать ID объекта и загружать данные через ViewModel с SavedStateHandle. Если объект простой — используйте Parcelable через kotlinx.parcelize. Передача больших объектов напрямую через аргументы (Bundle) ограничена лимитом ~1 MB и может вызвать TransactionTooLargeException.

Поддерживает ли Navigation Compose вложенные графы?

Да, через функцию navigation(route, startDestination) внутри NavHost. Вложенные графы имеют собственный startDestination и объединяются под общим route-префиксом. Это позволяет организовать модульную архитектуру с изолированными графами для каждого feature-модуля.

Как обработать системную кнопку Back в Navigation Compose?

NavController автоматически обрабатывает back press через BackHandler из Compose. Вызовите navController.popBackStack() при нажатии Back. Для кастомной обработки (подтверждение выхода) используйте BackHandler(enabled = condition) { callback } до вызова popBackStack().

Можно ли использовать Navigation Compose с Jetpack Compose Multiplatform?

На данный момент Navigation Compose не поддерживается в Compose Multiplatform. Для iOS-части кросс-платформенных проектов используйте Voyager или Decompose. Google работает над поддержкой KMP, но сроков выпуска нет. Для Android-only проектов Navigation Compose — единственный рекомендуемый вариант.

Итоги

  • Navigation Compose — библиотека Jetpack для декларативной навигации в Compose, работающая через граф маршрутов и NavController
  • NavController управляет back stack и предоставляет методы navigate, popBackStack для навигации
  • NavHost связывает контроллер с графом через composable(), поддерживая вложенные графы для модульной архитектуры
  • Аргументы передаются через NavType с поддержкой String, Int, Parcelable и Type-Safe Navigation с Kotlin Serialization
  • Deep Links настраиваются через navDeepLink с UriPattern для внешней навигации из URL и пушей
  • Анимация переходов задаётся через enterTransition, exitTransition с использованием Compose Animation API
  • Библиотека не поддерживает KMP и multi-back stack для BottomNavigation без дополнительной настройки

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также