如何在jetpack compose中制作带有阴影的圆角

Viv*_*odi 5 android kotlin android-jetpack-compose

我想为我的卡片视图制作带有阴影的圆角。我想看起来像这样

在此输入图像描述

我正在尝试在Box以下人员的帮助下Modifier

使用shadowandclip进行这样的排序

Box(
    modifier = Modifier
        .fillMaxSize()
        .shadow(1.dp)
        .clip(RoundedCornerShape(12.dp))
        .padding(
            start = 16.dp,
            end = 16.dp,
            top = 12.dp,
            bottom = 16.dp,
        )
) {
    // method in here
}
Run Code Online (Sandbox Code Playgroud)

看起来像这样

在此输入图像描述

现在我改成这样的clip顺序shadow

Box(
    modifier = Modifier
        .fillMaxSize()
        .clip(RoundedCornerShape(12.dp))
        .shadow(1.dp)
        .padding(
            start = 16.dp,
            end = 16.dp,
            top = 12.dp,
            bottom = 16.dp,
        )
) {
    // method in here
}
Run Code Online (Sandbox Code Playgroud)

它看起来像这样

在此输入图像描述

我现在不明白修饰符的顺序。有人可以指导我吗?

Thr*_*ian 16

TL;DR 仅使用 Modifier.shadow(elevation, shape),它也根据阴影高程进行剪辑。

@Stable
fun Modifier.shadow(
    elevation: Dp,
    shape: Shape = RectangleShape,
    clip: Boolean = elevation > 0.dp,
    ambientColor: Color = DefaultShadowColor,
    spotColor: Color = DefaultShadowColor,
)
Run Code Online (Sandbox Code Playgroud)

在理解 Modifiers 的顺序之前,我认为最好先解释一下 Modifier.shadow 的作用及其工作原理。

Modifier.shadow 基本上是一个白色背景(请参阅第一个示例,其中未分配背景)和可组合项周围的边框,具有一些模糊效果。如果您在没有背景的情况下绘制它,您将获得基于标高和专色的模糊矩形,并且它的顺序取决于它是在可组合项的后面还是前面绘制

在此输入图像描述

@Preview
@Composable
private fun ShadowSample() {

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {

        Text("Shadow Order")

        Box(
            modifier = Modifier
                .size(100.dp)
                .shadow(
                    elevation = 10.dp,
                spotColor = Color.Red,
                shape = RoundedCornerShape(8.dp)
                ),
            contentAlignment = Alignment.Center
        ) {
            Text("Hello World")
        }

        Spacer(modifier = Modifier.height(20.dp))
        Box(
            modifier = Modifier
                .background(Color.Red)
                .size(100.dp)
                .shadow(
                    elevation = 10.dp,
                    shape = RoundedCornerShape(8.dp)
                ),
            contentAlignment = Alignment.Center
        ) {
            Text("Hello World")
        }

        Spacer(modifier = Modifier.height(20.dp))

        Box(
            modifier = Modifier
                .shadow(
                    elevation = 10.dp,
                    shape = RoundedCornerShape(8.dp)
                )
                .background(Color.Red)
                .size(100.dp),
            contentAlignment = Alignment.Center
        ) {
            Text("Hello World")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个是没有任何背景的情况。第二个阴影是在背景之后绘制的,因此它是在可组合项前面绘制的,就像在它前面绘制边框或矩形一样。

Modifier.clip 将所有内容从您的可组合项中剪掉,包括任何绘图(没有剪辑,您可以从您的可组合项中绘制任何内容)或阴影,如下例所示

在此输入图像描述

在第一个示例中,我们剪切阴影和边框,这就是为什么您看不到任何阴影,并且绿色矩形边框被圆角矩形形状剪切。

在第二个示例中,阴影在剪辑之前,因此不会被剪辑,但绿色边框会被剪辑。

在第三个示例中,由于边框位于 Modifier.shadow 之前,因此它不会被剪切,正如您所看到的,它具有矩形形状。但是 Modifier.shadow 之后的任何内容都会被剪裁,因为 Modifier.shadow 附带的剪辑参数 true。

@Preview
@Composable
private fun ShadowSample2(){
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {

        Text("Clipping with Shadow")
        Box(
            modifier = Modifier
                .clip(RoundedCornerShape(8.dp))
                .shadow(
                    elevation = 10.dp,
                    RoundedCornerShape(8.dp)
                )
                .border(1.dp, Color.Green)
                .background(Color.White)
                .size(100.dp),
            contentAlignment = Alignment.Center
        ) {
            Text("Hello World")
        }

        Spacer(modifier = Modifier.height(10.dp))

        Box(
            modifier = Modifier

                .shadow(
                    elevation = 10.dp,
                    shape = RoundedCornerShape(8.dp)
                )
                .clip(RoundedCornerShape(8.dp))
                .border(1.dp, Color.Green)
                .background(Color.White)
                .size(100.dp),
            contentAlignment = Alignment.Center
        ) {
            Text("Hello World")
        }

        Spacer(modifier = Modifier.height(10.dp))

        Box(
            modifier = Modifier
                .border(1.dp, Color.Green)
                .shadow(
                    elevation = 10.dp,
                    shape = RoundedCornerShape(8.dp)
                )
                .background(Color.White)
                .size(100.dp),
            contentAlignment = Alignment.Center
        ) {
            Text("Hello World")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)