Анимация между пунктами назначения

NavDisplay предоставляет встроенные возможности анимации для создания плавных визуальных переходов при навигации пользователей по вашему приложению. Вы можете настроить эти анимации глобально для NavDisplay или для каждого NavEntry с помощью метаданных.

Переопределить переходы по умолчанию

NavDisplay использует ContentTransform s для определения того, как контент анимируется во время навигации. Вы можете переопределить поведение анимации по умолчанию, предоставив параметры перехода в NavDisplay .

  • transitionSpec : этот параметр определяет ContentTransform , применяемый при добавлении контента в стек переходов назад (т. е. при переходе вперед).
  • popTransitionSpec : этот параметр определяет ContentTransform , применяемый при удалении контента из стека переходов (т. е. при переходе назад).
  • predictivePopTransitionSpec : этот параметр определяет ContentTransform , применяемый при извлечении контента с помощью предиктивного жеста «назад».

Переопределять переходы на индивидуальном уровне NavEntry

Вы также можете определить пользовательские анимации для определенных NavEntry s, используя их метаданные. NavDisplay распознает специальные ключи метаданных для применения переходов для каждой записи:

  • NavDisplay.transitionSpec : используйте эту вспомогательную функцию для определения анимации прямой навигации.
  • NavDisplay.popTransitionSpec : используйте эту вспомогательную функцию для определения анимации обратной навигации для определенного NavEntry .
  • NavDisplay.predictivePopTransitionSpec : используйте эту вспомогательную функцию, чтобы определить анимацию для предиктивных жестов «назад» для определенного NavEntry .

Эти переходы метаданных для каждой записи переопределяют глобальные переходы 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 = NavDisplay.transitionSpec {
                                // Slide new content up, keeping the old content in place underneath
                                slideInVertically(
                                    initialOffsetY = { it },
                                    animationSpec = tween(1000)
                                ) togetherWith ExitTransition.KeepUntilTransitionsFinished
                            } + NavDisplay.popTransitionSpec {
                                // Slide old content down, revealing the new content in place underneath
                                EnterTransition.None togetherWith
                                    slideOutVertically(
                                        targetOffsetY = { it },
                                        animationSpec = tween(1000)
                                    )
                            } + NavDisplay.predictivePopTransitionSpec {
                                // 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)
                )
            }
        }
    }
}

Рисунок 1. Приложение с пользовательской анимацией.