我想实现这样的动画。
我设法实现了水平移动,但我不明白如何使旧屏幕变暗。
打开
NavigationDrawer
或 AlertDialog
时,Compose 中会出现类似的效果 - 后面的整个屏幕变暗。此效果的正确名称是什么?它是否有公共 API?
这是我当前的代码:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyAppTheme {
Surface(modifier = Modifier.fillMaxSize()) {
val navController = rememberNavController()
val animationDuration = 500
val startDestinationEnterAnimation: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) = {
slideIntoContainer(
towards = AnimatedContentTransitionScope.SlideDirection.Right,
animationSpec = tween(animationDuration),
initialOffset = { it / 2 }
)
}
val startDestinationExitAnimation: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) = {
slideOutOfContainer(
towards = AnimatedContentTransitionScope.SlideDirection.Left,
animationSpec = tween(animationDuration),
targetOffset = { it / 2 }
)
}
val destinationEnterAnimation: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) = {
slideIntoContainer(
towards = AnimatedContentTransitionScope.SlideDirection.Left,
animationSpec = tween(animationDuration),
)
}
val destinationExitAnimation: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) = {
slideOutOfContainer(
towards = AnimatedContentTransitionScope.SlideDirection.Right,
animationSpec = tween(animationDuration),
)
}
NavHost(
navController = navController,
startDestination = Constants.SCREEN_MAIN,
builder = {
composable(
route = Constants.SCREEN_MAIN,
enterTransition = startDestinationEnterAnimation,
exitTransition = startDestinationExitAnimation
) {
MainScreen(
onClickSettings = {
val route = Constants.SCREEN_SETTINGS
navController.navigate(route) {
popUpTo(route) {
inclusive = true
}
}
}
)
}
composable(
route = Constants.SCREEN_SETTINGS,
enterTransition = destinationEnterAnimation,
exitTransition = destinationExitAnimation
) {
SettingsScreen(onClickBack = {
if (navController.currentBackStackEntry?.lifecycle?.currentState == Lifecycle.State.RESUMED) {
navController.popBackStack()
}
})
}
}
)
}
}
}
}
}
我认为您无法通过导航动画 Api 实现这种外观 - 但当您导航到屏幕设置时,您可以在主屏幕可组合项顶部淡入黑色全屏框。
我测试了下面的代码,看起来没问题。重要的是,黑盒代码位于主屏幕代码下方,以便它呈现在主屏幕可组合的前面。
我已将缓动设置为 EaseOutCirc 但您可能会在这里找到更好的缓动 https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#EaseOutCirc()
Box(){
val showbox = remember {
mutableStateOf(false)
}
MainScreen(
onClickSettings = {
showbox.value = true
val route = Constants.SCREEN_SETTINGS
navController.navigate(route) {
popUpTo(route) {
inclusive = true
}
}
}
)
AnimatedVisibility(
visible = showbox.value,
enter = fadeIn(tween(750, easing = EaseOutCirc))
) {
Box(Modifier.fillMaxSize().background(Color.Black))
}
}