NavDisplay
提供了内置的动画功能,可在用户在应用中导航时创建流畅的视觉过渡。您可以为 NavDisplay
全局自定义这些动画,也可以使用元数据为每个 NavEntry
单独自定义这些动画。
替换默认过渡效果
NavDisplay
使用 ContentTransform
定义内容在导航期间的动画方式。您可以通过向 NavDisplay
提供过渡参数来替换默认的动画行为。
transitionSpec
:此参数定义当内容添加到返回堆栈时(即向前导航时)要应用的ContentTransform
。popTransitionSpec
:此参数定义当内容从返回堆栈中移除时(即向后导航时)要应用的ContentTransform
。predictivePopTransitionSpec
:此参数定义当内容通过预测性返回手势弹出时要应用的ContentTransform
。
在各个 NavEntry
级别替换过渡效果
您还可以使用元数据为特定的 NavEntry
定义自定义动画。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) ) } } } }