Navigation Compose API позволяет перемещаться между composable-функциями в приложении Compose, используя компонент, инфраструктуру и функции Jetpack Navigation.
На этой странице описывается, как перейти с Jetpack Navigation на основе фрагментов на Navigation Compose в рамках более масштабного перехода с интерфейса на основе представлений на Jetpack Compose.
Предварительные требования для переноса
Вы можете перейти на Navigation Compose, когда сможете заменить все фрагменты соответствующими composable-функциями экрана. Составные элементы экрана могут содержать смесь контента Compose и View, но все пункты назначения навигации должны быть составными, чтобы обеспечить миграцию Navigation Compose. До тех пор вы должны продолжать использовать компонент навигации на основе фрагментов в своей базе кода View и Compose. Дополнительную информацию можно найти в документации по совместимости навигации.
Этапы переноса
Независимо от того, следуете ли вы нашей рекомендованной стратегии переноса или используете другой подход, вы достигнете точки, когда все пункты назначения Navigation будут composable-функциями экрана, а фрагменты будут действовать только как контейнеры composable-функций. На этом этапе вы можете перейти на Navigation Compose.
Если ваше приложение уже соответствует шаблону проектирования UDF и нашему руководству по архитектуре, то при переходе на Jetpack Compose и Navigation Compose вам не потребуется проводить рефакторинг других уровней приложения, кроме уровня пользовательского интерфейса.
Чтобы перейти на Navigation Compose, выполните следующие действия:
- Добавьте в приложение зависимость Navigation Compose.
Создайте composable-функцию
App-levelи добавьте ее вActivityв качестве точки входа Compose, заменив настройку макета View:class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
Создайте типы для каждого пункта назначения. Используйте
data objectдля целевых страниц, которые не требуют данных, иdata classилиclassдля целевых страниц, которые требуют данных.@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
Настройте
NavControllerв месте, где все composable-функции, которым нужно на него ссылаться, имеют к нему доступ (обычно это внутри вашей composable-функцииApp). Этот подход соответствует принципам передачи состояния и позволяет использоватьNavControllerв качестве источника достоверных данных для навигации между составными экранами и поддержки обратного стека.@Composable fun SampleApp() { val navController = rememberNavController() // ... }
Создайте
NavHostприложения внутри composable-функцииAppи передайтеnavController:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
Добавьте пункты назначения (
composable), чтобы создать граф навигации. Если каждый экран уже перенесен в Compose, на этом шаге нужно только извлечь composable-функции экранов из фрагментов в пункты назначенияcomposable:class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { // FirstScreen(...) EXTRACT FROM HERE } } } } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen(/* ... */) // EXTRACT TO HERE } composable<Second> { SecondScreen(/* ... */) } // ... } }
Если вы следовали рекомендациям по архитектуре интерфейса Compose, в частности по передаче
ViewModelи событий навигации в composable-функции, то следующим шагом будет изменение способа передачиViewModelв composable-функцию каждого экрана. Часто можно использовать внедрение Hilt и его точку интеграции с Compose и Navigation черезhiltViewModel:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
Замените все вызовы навигации
findNavController()вызовамиnavControllerи передайте их в качестве событий навигации каждому составному экрану, а не передавайте весьnavController. Этот подход соответствует рекомендациям по предоставлению событий из composable-функций вызывающим объектам и сохраняетnavControllerв качестве единого источника достоверных данных.Данные можно передать в пункт назначения, создав экземпляр класса маршрута, определенного для этого пункта назначения. Затем его можно получить либо напрямую из записи обратного стека в пункте назначения, либо из объекта
ViewModelс помощью методаSavedStateHandle.toRoute().@Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen( onButtonClick = { // findNavController().navigate(firstScreenToSecondScreenAction) navController.navigate(Second(id = "ABC")) } ) } <compos>ableSecond { backSt>ackEntry - val secondRoute = backStackEnt<ry.toR>outeSecond() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // .nippets.kt
Удалите все фрагменты, соответствующие макеты XML, ненужные ресурсы навигации и другие ресурсы, а также устаревшие зависимости фрагментов и Jetpack Navigation.
Те же шаги с дополнительными сведениями о Navigation Compose можно найти в документации по настройке.
Примеры использования
Независимо от того, какой компонент навигации вы используете, применяются одни и те же принципы навигации.
Ниже приведены распространенные сценарии переноса.
- Как перейти к composable-функции
- Навигация с аргументами
- Ссылки на контент
- Вложенная навигация
- Интеграция с нижней панелью навигации
- Интеграция с пользовательским компонентом навигации
Подробную информацию об этих сценариях использования можно найти в статье Навигация с помощью Compose.
Получение сложных данных при навигации
Мы настоятельно рекомендуем не передавать сложные объекты данных при навигации. Вместо этого передавайте минимально необходимую информацию, например уникальный идентификатор или другую форму идентификатора, в качестве аргументов при выполнении действий навигации. Сложные объекты следует хранить в виде данных в едином источнике достоверных данных, например в слое данных. Подробнее о том, как получать сложные данные во время навигации…
Если ваши фрагменты передают сложные объекты в качестве аргументов, сначала проведите рефакторинг кода, чтобы эти объекты можно было хранить и получать из уровня данных. Примеры можно найти в репозитории Now in Android.
Ограничения
В этом разделе описываются текущие ограничения для Navigation Compose.
Постепенный переход на Navigation Compose
В настоящее время вы не можете использовать Navigation Compose, если в коде в качестве пунктов назначения используются фрагменты. Чтобы начать использовать Navigation Compose, все ваши пункты назначения должны быть составными. Вы можете отслеживать этот запрос на добавление функции в системе отслеживания ошибок.
Анимация переходов
Начиная с версии Navigation 2.7.0-alpha01, поддержка настройки пользовательских переходов, ранее доступная в AnimatedNavHost, теперь напрямую поддерживается в NavHost. Более подробные сведения можно найти в примечаниях к выпуску.
Подробнее…
Дополнительную информацию о переходе на Navigation Compose можно найти в следующих ресурсах:
- Практическая работа по Navigation Compose. Изучите основы Navigation Compose на практике.
- Репозиторий Now in Android. Полностью функциональное приложение для Android, созданное на Kotlin и Jetpack Compose. Оно соответствует рекомендациям по разработке и дизайну для Android и включает Navigation Compose.
- Перенос Sunflower на Jetpack Compose. Запись в блоге, в которой описывается перенос примера приложения Sunflower с View на Compose, включая переход на Navigation Compose.
- Jetnews для всех экранов. Запись в блоге, в которой рассказывается о рефакторинге и переносе примера Jetnews для поддержки всех экранов с помощью Jetpack Compose и Navigation Compose.
Рекомендуем
- Примечание. Текст ссылки показывается, когда JavaScript отключен.
- Навигация с помощью Compose
- Compose и другие библиотеки
- Другие причины