NavDisplay предоставляет встроенные возможности анимации для создания плавных визуальных переходов по мере перемещения пользователей по вашему приложению. Вы можете настроить эти анимации глобально для NavDisplay или на уровне Scene с помощью метаданных.
Разберитесь во встроенных возможностях анимации.
NavDisplay использует API ContentTransform для определения того, как анимируется контент во время навигации. NavDisplay автоматически анимирует переходы между сценами, когда изменяется ключ, производный от класса текущей сцены и ее свойства key . При изменении этого ключа NavDisplay использует ContentTransform для типа перехода — вперед, назад или предиктивный возврат — из соответствующей сцены в переходе. Если ContentTransform не определен, NavDisplay возвращается к использованию соответствующего перехода по умолчанию .
Переопределить переходы по умолчанию
Вы можете переопределить поведение анимации по умолчанию, указав параметры перехода в NavDisplay .
-
transitionSpec: Этот параметр определяетContentTransform, применяемый при добавлении контента в стек возврата (т. е. при переходе вперед). -
popTransitionSpec: Этот параметр определяетContentTransform, применяемый при удалении контента из стека "Назад" (т.е. при переходе назад). -
predictivePopTransitionSpec: Этот параметр определяетContentTransform, применяемый при удалении контента с помощью предиктивного жеста "назад".
Переопределение переходов на уровне Scene
Вы можете использовать метаданные для определения пользовательских анимаций для отдельных сцен, используя следующие ключи метаданных, определенные NavDisplay :
-
NavDisplay.TransitionKey: Анимация прямой навигации. -
NavDisplay.PopTransitionKey: Анимация обратной навигации. -
NavDisplay.PredictivePopTransitionKey: Анимация возврата назад с функцией прогнозирования.
Если эти переходы на уровне сцены заданы, они используются вместо соответствующих настроек по умолчанию, установленных в NavDisplay .
Следующий фрагмент кода демонстрирует как глобальные переходы NavDisplay , так и переопределение на уровне отдельных элементов NavEntry :
@Serializable data object ScreenA : NavKey @Serializable data object ScreenB : NavKey @Serializable data object ScreenC : NavKey class AnimatedNavDisplayActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Scaffold { paddingValues -> val backStack = rememberNavBackStack(ScreenA) NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = entryProvider { entry<ScreenA> { ContentOrange("This is Screen A") { Button(onClick = { backStack.add(ScreenB) }) { Text("Go to Screen B") } } } entry<ScreenB> { ContentMauve("This is Screen B") { Button(onClick = { backStack.add(ScreenC) }) { Text("Go to Screen C") } } } entry<ScreenC>( metadata = metadata { put(NavDisplay.TransitionKey) { // Slide new content up, keeping the old content in place underneath slideInVertically( initialOffsetY = { it }, animationSpec = tween(1000) ) togetherWith ExitTransition.KeepUntilTransitionsFinished } put(NavDisplay.PopTransitionKey) { // Slide old content down, revealing the new content in place underneath EnterTransition.None togetherWith slideOutVertically( targetOffsetY = { it }, animationSpec = tween(1000) ) } put(NavDisplay.PredictivePopTransitionKey) { // Slide old content down, revealing the new content in place underneath EnterTransition.None togetherWith slideOutVertically( targetOffsetY = { it }, animationSpec = tween(1000) ) } } ) { ContentGreen("This is Screen C") } }, transitionSpec = { // Slide in from right when navigating forward slideInHorizontally(initialOffsetX = { it }) togetherWith slideOutHorizontally(targetOffsetX = { -it }) }, popTransitionSpec = { // Slide in from left when navigating back slideInHorizontally(initialOffsetX = { -it }) togetherWith slideOutHorizontally(targetOffsetX = { it }) }, predictivePopTransitionSpec = { // Slide in from left when navigating back slideInHorizontally(initialOffsetX = { -it }) togetherWith slideOutHorizontally(targetOffsetX = { it }) }, modifier = Modifier.padding(paddingValues) ) } } } }
Переходы между сценами через элементы навигации.
В приложениях, создающих пользовательские макеты с использованием сцен , возможно включение элемента NavEntry в свойство entries обеих сцен во время перехода. Внутри NavDisplay проверяет, отображается ли каждый элемент не более чем в одной сцене одновременно, что может привести к резким переходам при изменении сцены, отображающей NavEntry . Для плавной анимации элементов между сценами можно обернуть NavDisplay в SharedTransitionLayout и передать SharedTransitionScope элементу NavDisplay , как показано в следующем примере:
SharedTransitionLayout { NavDisplay( // ... sharedTransitionScope = this ) }