API Navigation Compose позволяет перемещаться между составными объектами в приложении Compose, используя при этом преимущества компонента, инфраструктуры и функций Jetpack Navigation .
На этой странице описывается, как перейти от навигации Jetpack на основе фрагментов к Navigation Compose в рамках более крупной миграции пользовательского интерфейса на основе представлений в Jetpack Compose.
Предварительные условия миграции
Вы можете перейти на Navigation Compose, как только сможете заменить все свои фрагменты соответствующими компонентами экрана . Составные элементы экрана могут содержать смесь содержимого Compose и View , но все пункты назначения навигации должны быть составными, чтобы можно было выполнить миграцию Navigation Compose. До тех пор вам следует продолжать использовать компонент навигации на основе фрагментов в базе кода взаимодействия View и Compose. Дополнительные сведения см. в документации по взаимодействию навигации .
Использование Navigation Compose в приложении, предназначенном только для создания сообщений, не является обязательным условием. Вы можете продолжать использовать компонент навигации на основе фрагментов , пока сохраняете фрагменты для размещения компонуемого контента .
Этапы миграции
Независимо от того, следуете ли вы нашей рекомендуемой стратегии миграции или используете другой подход, вы достигнете точки, когда все пункты назначения навигации будут компонуемыми на экране, а фрагменты будут действовать только как компонуемые контейнеры. На этом этапе вы можете перейти на Navigation Compose.
Если ваше приложение уже соответствует шаблону проектирования UDF и нашему руководству по архитектуре , переход на Jetpack Compose и Navigation Compose не должен требовать серьезных рефакторингов других уровней вашего приложения, кроме уровня пользовательского интерфейса.
Чтобы перейти на Navigation Compose, выполните следующие действия:
- Добавьте зависимость Navigation Compose в свое приложение.
Создайте компонуемый объект
App-level
и добавьте его в своюActivity
в качестве точки входа для создания, заменив настройку макета представления: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
в месте, где все компонуемые элементы, которым необходимо ссылаться на него, имеют к нему доступ (обычно это находится внутри компонуемогоApp
). Этот подход следует принципам подъема состояния и позволяет использоватьNavController
в качестве источника данных для навигации между компонуемыми экранами и поддержки обратного стека:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
Создайте
NavHost
вашего приложения внутри составногоApp
и передайтеnavController
:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
Добавьте
composable
пункты назначения, чтобы построить навигационный граф. Если каждый экран ранее был перенесен в Compose, этот шаг состоит только из извлечения этих компонуемых экранов из ваших фрагментов в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
и события навигации должны передаваться в составные элементы, следующим шагом будет изменение способа предоставленияViewModel
для каждого компонуемого экрана. Вы часто можете использовать Hilt-инъекцию и ее точку интеграции с Compose и Navigation черезhiltViewModel
:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
Замените все навигационные вызовы
findNavController()
вызовамиnavController
и передайте их как события навигации на каждый составной экран, а не передавайте весьnavController
. Этот подход соответствует лучшим практикам предоставления событий из составных функций вызывающим сторонам и сохраняет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")) } ) } composable<Second> { backStackEntry -> val secondRoute = backStackEntry.toRoute<Second>() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // ... } }
Удалите все фрагменты, соответствующие макеты XML, ненужную навигацию и другие ресурсы, а также устаревшие зависимости фрагментов и навигации Jetpack.
Те же действия, а также дополнительные сведения, связанные с Navigation Compose, можно найти в документации по установке .
Распространенные случаи использования
Независимо от того, какой компонент навигации вы используете, применяются одни и те же принципы навигации .
Общие случаи использования при миграции включают следующее:
- Перейдите к составному элементу
- Навигация с аргументами
- Глубокие ссылки
- Вложенная навигация
- Интеграция с нижней панелью навигации
- Интеграция с пользовательским навигационным компонентом
Более подробную информацию об этих вариантах использования см. в разделе «Навигация с помощью Compose» .
Получение сложных данных при навигации
Мы настоятельно рекомендуем не обходить сложные объекты данных при навигации. Вместо этого передайте минимально необходимую информацию, например уникальный идентификатор или другую форму идентификатора, в качестве аргументов при выполнении действий навигации. Сложные объекты следует хранить в виде данных в одном источнике достоверности, например на уровне данных . Дополнительную информацию см. в разделе Получение сложных данных при навигации .
Если ваши фрагменты передают сложные объекты в качестве аргументов, сначала рассмотрите возможность рефакторинга вашего кода таким образом, чтобы можно было хранить и извлекать эти объекты из уровня данных. Примеры см. в репозитории Now in Android .
Ограничения
В этом разделе описаны текущие ограничения для Navigation Compose.
Инкрементальный переход на Navigation Compose
В настоящее время вы не можете использовать Navigation Compose, продолжая использовать фрагменты в качестве пунктов назначения в своем коде. Чтобы начать использовать Navigation Compose, все ваши пункты назначения должны быть составными. Вы можете отслеживать этот запрос на функцию в Issue Tracker .
Анимация перехода
Начиная с Navigation 2.7.0-alpha01 , поддержка настройки пользовательских переходов, ранее существовавшая из AnimatedNavHost
, теперь напрямую поддерживается в NavHost
. Прочтите примечания к выпуску для получения дополнительной информации.
Узнать больше
Дополнительные сведения о переходе на Navigation Compose см. в следующих ресурсах:
- Лаборатория разработки Navigation Compose : изучите основы Navigation Compose с помощью практической лаборатории разработки кода.
- Теперь в репозитории Android : полнофункциональное приложение для Android, полностью созданное с помощью Kotlin и Jetpack Compose, которое следует передовым практикам проектирования и разработки Android и включает в себя Navigation Compose.
- Миграция Sunflower в Jetpack Compose : запись в блоге, в которой документируется путь миграции примера приложения Sunflower из Views в Compose, который также включает миграцию в Navigation Compose.
- Jetnews для каждого экрана : сообщение в блоге, в котором документируется рефакторинг и миграция примера Jetnews для поддержки всех экранов с помощью Jetpack Compose и Navigation Compose.
Рекомендуется для вас
- Примечание. Текст ссылки отображается, когда JavaScript отключен.
- Навигация с помощью Compose
- Compose и другие библиотеки
- Другие соображения
API Navigation Compose позволяет перемещаться между составными объектами в приложении Compose, используя при этом преимущества компонента, инфраструктуры и функций Jetpack Navigation .
На этой странице описывается, как перейти от навигации Jetpack на основе фрагментов к Navigation Compose в рамках более крупной миграции пользовательского интерфейса на основе представлений в Jetpack Compose.
Предварительные условия миграции
Вы можете перейти на Navigation Compose, как только сможете заменить все свои фрагменты соответствующими компонентами экрана . Составные элементы экрана могут содержать смесь содержимого Compose и View , но все пункты назначения навигации должны быть составными, чтобы можно было выполнить миграцию Navigation Compose. До тех пор вам следует продолжать использовать компонент навигации на основе фрагментов в базе кода взаимодействия View и Compose. Дополнительную информацию см. в документации по взаимодействию навигации .
Использование Navigation Compose в приложении, предназначенном только для создания сообщений, не является обязательным условием. Вы можете продолжать использовать компонент навигации на основе фрагментов , пока сохраняете фрагменты для размещения компонуемого контента .
Этапы миграции
Независимо от того, следуете ли вы нашей рекомендуемой стратегии миграции или используете другой подход, вы достигнете точки, когда все пункты назначения навигации будут компонуемыми на экране, а фрагменты будут действовать только как компонуемые контейнеры. На этом этапе вы можете перейти на Navigation Compose.
Если ваше приложение уже соответствует шаблону проектирования UDF и нашему руководству по архитектуре , переход на Jetpack Compose и Navigation Compose не должен требовать серьезных рефакторингов других уровней вашего приложения, кроме уровня пользовательского интерфейса.
Чтобы перейти на Navigation Compose, выполните следующие действия:
- Добавьте зависимость Navigation Compose в свое приложение.
Создайте компонуемый объект
App-level
и добавьте его в своюActivity
в качестве точки входа для создания, заменив настройку макета представления: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
в месте, где все компонуемые элементы, которым необходимо ссылаться на него, имеют к нему доступ (обычно это находится внутри компонуемогоApp
). Этот подход следует принципам подъема состояния и позволяет использоватьNavController
в качестве источника данных для навигации между компонуемыми экранами и поддержки обратного стека:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
Создайте
NavHost
вашего приложения внутри составногоApp
и передайтеnavController
:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
Добавьте
composable
пункты назначения, чтобы построить навигационный граф. Если каждый экран ранее был перенесен в Compose, этот шаг состоит только из извлечения этих компонуемых экранов из ваших фрагментов в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
и события навигации должны передаваться в составные элементы, следующим шагом будет изменение способа предоставленияViewModel
для каждого компонуемого экрана. Вы часто можете использовать Hilt-инъекцию и ее точку интеграции с Compose и Navigation черезhiltViewModel
:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
Замените все навигационные вызовы
findNavController()
вызовамиnavController
и передайте их как события навигации на каждый составной экран, а не передавайте весьnavController
. Этот подход соответствует лучшим практикам предоставления событий из составных функций вызывающим сторонам и сохраняет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")) } ) } composable<Second> { backStackEntry -> val secondRoute = backStackEntry.toRoute<Second>() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // ... } }
Удалите все фрагменты, соответствующие макеты XML, ненужную навигацию и другие ресурсы, а также устаревшие зависимости фрагментов и навигации Jetpack.
Вы можете найти те же действия с дополнительной информацией, связанной с Navigation Compose, в документации по установке .
Распространенные случаи использования
Независимо от того, какой компонент навигации вы используете, применяются одни и те же принципы навигации .
Общие случаи использования при миграции включают следующее:
- Перейдите к составному элементу
- Навигация с аргументами
- Глубокие ссылки
- Вложенная навигация
- Интеграция с нижней панелью навигации
- Интеграция с пользовательским навигационным компонентом
Более подробную информацию об этих вариантах использования см. в разделе «Навигация с помощью Compose» .
Получение сложных данных при навигации
Мы настоятельно рекомендуем не обходить сложные объекты данных при навигации. Вместо этого передайте минимально необходимую информацию, например уникальный идентификатор или другую форму идентификатора, в качестве аргументов при выполнении действий навигации. Сложные объекты следует хранить в виде данных в одном источнике достоверности, например на уровне данных . Дополнительную информацию см. в разделе Получение сложных данных при навигации .
Если ваши фрагменты передают сложные объекты в качестве аргументов, сначала рассмотрите возможность рефакторинга вашего кода таким образом, чтобы можно было хранить и извлекать эти объекты из уровня данных. Примеры см. в репозитории Now in Android .
Ограничения
В этом разделе описаны текущие ограничения для Navigation Compose.
Инкрементальный переход на Navigation Compose
В настоящее время вы не можете использовать Navigation Compose, продолжая использовать фрагменты в качестве пунктов назначения в своем коде. Чтобы начать использовать Navigation Compose, все ваши пункты назначения должны быть составными. Вы можете отслеживать этот запрос на функцию в Issue Tracker .
Анимация перехода
Начиная с Navigation 2.7.0-alpha01 , поддержка настройки пользовательских переходов, ранее существовавшая из AnimatedNavHost
, теперь напрямую поддерживается в NavHost
. Прочтите примечания к выпуску для получения дополнительной информации.
Узнать больше
Дополнительные сведения о переходе на Navigation Compose см. в следующих ресурсах:
- Лаборатория разработки Navigation Compose : изучите основы Navigation Compose с помощью практической лаборатории разработки кода.
- Теперь в репозитории Android : полнофункциональное приложение для Android, полностью созданное с помощью Kotlin и Jetpack Compose, которое следует передовым практикам проектирования и разработки Android и включает в себя Navigation Compose.
- Миграция Sunflower в Jetpack Compose : запись в блоге, в которой документируется путь миграции примера приложения Sunflower из Views в Compose, который также включает миграцию в Navigation Compose.
- Jetnews для каждого экрана : сообщение в блоге, в котором документируется рефакторинг и миграция примера Jetnews для поддержки всех экранов с помощью Jetpack Compose и Navigation Compose.
Рекомендуется для вас
- Примечание. Текст ссылки отображается, когда JavaScript отключен.
- Навигация с помощью Compose
- Compose и другие библиотеки
- Другие соображения