API Navigation Compose позволяет перемещаться между компонентами в приложении Compose, используя при этом преимущества компонентов, инфраструктуры и функций Jetpack Navigation .
На этой странице описывается, как осуществить миграцию с навигации Jetpack на основе фрагментов на Navigation Compose в рамках более масштабной миграции пользовательского интерфейса на основе представлений на Jetpack Compose.
Миграционные предпосылки
Переход на Navigation Compose возможен, как только вы сможете заменить все ваши фрагменты соответствующими компонентами для экранов . Компоненты для экранов могут содержать как контент Compose, так и контент View , но все навигационные элементы должны быть компонентами для обеспечения возможности перехода на Navigation Compose. До тех пор следует продолжать использовать компоненты навигации на основе фрагментов в коде взаимодействия View и Compose. Дополнительную информацию см. в документации по взаимодействию навигации .
Использование Navigation Compose в приложении, использующем только Compose, не является обязательным условием. Вы можете продолжать использовать компонент навигации на основе фрагментов , если сохраните фрагменты для размещения вашего создаваемого контента .
Этапы миграции
Независимо от того, следуете ли вы нашей рекомендуемой стратегии миграции или используете другой подход, вы достигнете точки, когда все элементы навигации будут представлять собой составные части экрана, а фрагменты будут выступать только в качестве составных контейнеров. На этом этапе вы можете перейти к использованию Navigation Compose.
Если ваше приложение уже использует шаблон проектирования UDF и наше руководство по архитектуре , переход на Jetpack Compose и Navigation Compose не должен потребовать существенной рефакторизации других слоев вашего приложения, за исключением слоя пользовательского интерфейса.
Для перехода на Navigation Compose выполните следующие действия:
- Добавьте зависимость Navigation Compose в ваше приложение.
Создайте компонент
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в таком месте, где все компонуемые объекты, которым необходимо на него ссылаться, будут иметь к нему доступ (обычно это находится внутри вашего компонуемого объекта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 UI , в частности, как передавать
ViewModelи события навигации в компонуемые объекты, следующим шагом будет изменение способа предоставленияViewModelкаждому компонуемому экрану. Часто можно использовать внедрение Hilt и его точку интеграции с Compose и навигацией через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» .
Получение сложных данных при навигации
Мы настоятельно рекомендуем не передавать сложные объекты данных при навигации. Вместо этого передавайте в качестве аргументов при выполнении навигационных действий минимально необходимую информацию, такую как уникальный идентификатор или другой вид идентификации. Сложные объекты следует хранить как данные в едином источнике достоверной информации, например, в слое данных . Для получения дополнительной информации см. раздел «Получение сложных данных при навигации» .
Если ваши фрагменты передают сложные объекты в качестве аргументов, сначала подумайте о рефакторинге кода таким образом, чтобы он позволял хранить и получать эти объекты из слоя данных. Примеры можно найти в репозитории Now in Android .
Ограничения
В этом разделе описаны текущие ограничения функции Navigation Compose.
Постепенный переход на Navigation Compose
В настоящее время вы не можете использовать Navigation Compose, если в вашем коде в качестве целевых объектов используются фрагменты. Чтобы начать использовать Navigation Compose, все ваши целевые объекты должны быть компонуемыми. Вы можете отслеживать этот запрос на добавление функции в системе отслеживания ошибок .
Анимация переходов
Начиная с версии 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 и другие
- Другие соображения