我想将褪色的底部栏背景添加到我制作的自定义导航栏中。
它接受透明颜色和纯色,但如果我想在那里放置verticalGradient,它只返回纯色。如果我在任何其他组件(例如 Box)中使用它,则不会发生此行为。
这可能是 Scaffold 组件的错误,但我不确定。
我想要实现的基本上是我在脚手架中的内容中有verticalScroll,如果我向下滚动并且内容在buttomBar后面,它会被其背景剪裁,背景应该是透明的顶部并慢慢褪色为纯色(这就是为什么我想用带有 VerticalGradient 的 Box 包裹它)。如果我将该框设置为透明,它是透明的,并且不会剪切我的内容,但由于某种原因不支持渐变。无论我在那里设置什么 startY/endY,它都会变成纯色。
我在屏幕背景组件中将这种技术与 VerticalGradient 一起使用,其中底部组件的边缘已褪色,并且其工作没有任何问题。只是如果它用在 Scaffold BottomBar 中,它就会被忽略。
val backgroundColor = Brush.verticalGradient(
colors = listOf(
Color.Transparent,
tabColors.backgroundBottom,
),
startY = 0f,
endY = 50f,
tileMode = TileMode.Clamp,
)
Scaffold (
bottomBar = {
if (isTabBarVisible) {
Box(
modifier = Modifier
.fillMaxWidth()
.background(backgroundColor)
.padding(16.dp)
) {
TabBar(
navController = navController,
)
}
}
}
) { innerPadding ->
NavHost(
modifier = Modifier.padding(innerPadding),
navController = navController,
startDestination = Screen.SplashData,
) {
... navigation to screens
}
}
这是我想要实现的视觉表示。
白色==透明
可滚动内容 == NavHost 显示的内容(具有生命周期的可组合屏幕)
“淡入淡出”背景应该是选项卡栏的一部分,因为导航底部栏隐藏在内容(屏幕)中,我不想在那里淡入淡出。
如果我传递verticalGradient(它将非透明颜色作为实心颜色),这就是现在的样子,这会导致选项卡栏(底部栏)后面的可滚动内容被剪裁。
这不是一个错误。 Scaffold 首先测量
bottomBar
槽内容,然后使用constraints.maxHeight-bottomBar 总高度测量 content
槽。然后它会像 Column 一样将内容放置在内容下方,然后将 BottomBar 放置在内容下方。
您可以添加 BottomBar 作为内容槽的一部分。对于 Snackbar,您可以覆盖 SnackBarHost 并将填充添加到与 BottomBar 一样大的底部。
@Composable
fun Test() {
val scaffoldState = rememberScaffoldState()
val coroutineScope = rememberCoroutineScope()
Scaffold(
scaffoldState = scaffoldState,
modifier = Modifier.systemBarsPadding(),
snackbarHost = {
SnackbarHost(
modifier = Modifier.padding(bottom = 48.dp),
hostState = it
)
}
) { paddingValues: PaddingValues ->
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize()
.border(2.dp, Color.Blue),
contentAlignment = Alignment.BottomStart
) {
Column(
modifier = Modifier.fillMaxSize()
) {
Button(
onClick = {
coroutineScope.launch {
scaffoldState.snackbarHostState.showSnackbar("Hello world")
}
}
) {
Text("Show snackbar")
}
}
Column(
modifier = Modifier.height(48.dp).fillMaxWidth().background(
brush = Brush.verticalGradient(listOf(Color.Red, Color.Green))
)
) {
Text("Bottom Bar Mock")
}
}
}
}