使用accompanist-insets时TopAppBar变透明,如何设置为不透明导航栏?
问题原因
你看到的TopAppBar透明本质是布局层级和内边距设置错误导致的:Box容器中LazyColumn写在TopAppBar之后,默认层级更高,会直接覆盖在导航栏上层,看起来就像导航栏是透明的。同时你外层重复添加了系统栏适配,也会影响导航栏的展示效果。
解决方法
按照如下规则修改代码即可实现纯色导航栏,同时保留你要的「内容从导航栏下方延伸、上滑隐藏导航栏」的效果:
- 调整组件顺序,将TopAppBar放到LazyColumn之后,确保导航栏层级更高不会被列表遮盖
- 移除外层Surface的全局系统栏适配,改为分别给导航栏和列表做单独的Insets适配
- 给LazyColumn添加对应高度的顶部内容内边距,保证初始状态列表内容从导航栏下方开始展示
修改后完整代码
val scrollState = rememberLazyListState() val isScrollStateChanged = scrollState.firstVisibleItemScrollOffset != 0 val position by animateFloatAsState(if (isScrollStateChanged) 0f else -45f) val listItems = (1..100).toList() // Material2 TopAppBar默认高度为56.dp val topAppBarHeight = 56.dp ProvideWindowInsets { Surface( modifier = Modifier.fillMaxSize(), color = Color.White ) { Box(Modifier.fillMaxSize()) { LazyColumn( state = scrollState, // 给列表设置顶部内边距=状态栏高度+导航栏高度,底部适配导航栏高度 contentPadding = PaddingValues( top = WindowInsets.statusBars.asPaddingValues().calculateTopPadding() + topAppBarHeight, bottom = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() ), // 滚动时内容可以滑到导航栏下方,设为true则内容完全不会滑入导航栏区域 clipToPadding = false ) { items(items = listItems) { Text( "Hello $it", Modifier .padding(20.dp) .fillMaxWidth() ) } } // TopAppBar放在列表后,层级更高不会被遮盖 TopAppBar( content = { Text("Hello nav bar!") }, modifier = Modifier .offset(0.dp, position.dp) .alpha(min(1f, 1 + (position / 45f))) // 单独适配状态栏高度,避免和系统状态栏重叠 .statusBarsPadding(), backgroundColor = Color.Red ) } } }
修改后导航栏的红色背景会正常显示,不会再出现透明的问题。
内容的提问来源于stack exchange,提问作者Sreekant Shenoy
相关产品推荐
相关产品推荐

