BottomNavigation动画启动前出现白色背景的问题排查
我尝试为BottomNavigation添加从底部滑入的显示动画,以下是实现代码:
@Composable private fun BottomNavImpl() { Scaffold( bottomBar = { var isBottomBarVisible: Boolean by remember { mutableStateOf(false) } LaunchedEffect(Unit) { delay(2000) isBottomBarVisible = true } AnimatedVisibility( visible = isBottomBarVisible, enter = slideInVertically( initialOffsetY = { it }, animationSpec = tween( durationMillis = 500, easing = FastOutSlowInEasing ) ), exit = slideOutVertically( targetOffsetY = { it }, animationSpec = tween( durationMillis = 300, easing = FastOutSlowInEasing ) ) ) { NavigationBar( containerColor = Color.Red, ) { repeat(3) { NavigationBarItem( icon = { Icon( modifier = Modifier, painter = painterResource(android.R.drawable.ic_menu_add), contentDescription = null, ) }, selected = false, onClick = { } ) } } } }, content = { paddingValues -> Box( modifier = Modifier .fillMaxSize() .padding(paddingValues) .background(Color.Green) ) { } } ) }
实际运行效果显示:动画启动前会先出现全屏高度的白色背景,之后才执行滑入动画(效果见动图:
)。请问我遗漏了什么导致该问题?
问题原因
你将AnimatedVisibility直接放在Scaffold的bottomBar参数中,Scaffold的底部栏区域默认会填充全屏宽度,而当AnimatedVisibility处于不可见状态时,内部的NavigationBar还未完成布局,此时AnimatedVisibility会占据全屏高度的空白区域,且默认背景为白色,这就导致了动画启动前的全屏白色问题。
解决方法
核心是约束AnimatedVisibility的尺寸为内容的固有大小,避免它占据多余空间,同时可以设置初始状态为Gone让组件完全不占位。
修改后的代码示例
@Composable private fun BottomNavImpl() { var isBottomBarVisible: Boolean by remember { mutableStateOf(false) } LaunchedEffect(Unit) { delay(2000) isBottomBarVisible = true } Scaffold( bottomBar = { AnimatedVisibility( visible = isBottomBarVisible, enter = slideInVertically( initialOffsetY = { it }, animationSpec = tween( durationMillis = 500, easing = FastOutSlowInEasing ) ), exit = slideOutVertically( targetOffsetY = { it }, animationSpec = tween( durationMillis = 300, easing = FastOutSlowInEasing ) ), // 关键:约束尺寸为内容大小,避免占据全屏 modifier = Modifier.wrapContentSize(), // 设置初始状态为Gone,不可见时完全不占位 visibleState = remember { MutableTransitionState(Visibility.Gone) } ) { NavigationBar( containerColor = Color.Red, ) { repeat(3) { NavigationBarItem( icon = { Icon( modifier = Modifier, painter = painterResource(android.R.drawable.ic_menu_add), contentDescription = null, ) }, selected = false, onClick = { } ) } } } }, content = { paddingValues -> Box( modifier = Modifier .fillMaxSize() .padding(paddingValues) .background(Color.Green) ) { } } ) }
关键修改点
- 添加
Modifier.wrapContentSize():让AnimatedVisibility仅包裹内部NavigationBar的尺寸,不会拉伸至全屏。 - 设置
visibleState = remember { MutableTransitionState(Visibility.Gone) }:初始状态为Gone,此时组件完全不占据布局空间,避免空白区域出现。
内容的提问来源于stack exchange,提问作者Sirop4ik
相关产品推荐
相关产品推荐

