Jetpack Compose:BottomBar 中的透明“淡入淡出”渐变

问题描述 投票:0回答:1

我想将褪色的底部栏背景添加到我制作的自定义导航栏中。

它接受透明颜色和纯色,但如果我想在那里放置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 显示的内容(具有生命周期的可组合屏幕)

“淡入淡出”背景应该是选项卡栏的一部分,因为导航底部栏隐藏在内容(屏幕)中,我不想在那里淡入淡出。

enter image description here

如果我传递verticalGradient(它将非透明颜色作为实心颜色),这就是现在的样子,这会导致选项卡栏(底部栏)后面的可滚动内容被剪裁。

enter image description here

android android-jetpack-compose
1个回答
0
投票

这不是一个错误。 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")
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.