繁体   English   中英

Jetpack Compose 图标阴影/高度

[英]Jetpack Compose icon shadow/elevation

有没有办法在 Jetpack Compose 中有一个带有阴影/高度的图标(带有 ImageVector)组件?

我想用一个提升的 Icon 制作一个 IconButton 但似乎没有解决这个问题的方法。 Modifier.shadow()之类的东西只会在我的图标周围绘制一个阴影框,并且 Icon 组件本身没有海拔参数。

乍一看,这张票似乎是如何在 Jetpack Compose 中为图标添加阴影/边框/高程的副本,但这张票并不是指与 ImageVector 结合的 Icon 组件。 此外,建议的解决方案不起作用,并且在 6 个月内没有更新。

为了进一步澄清,我希望我的图标看起来像这样:

带阴影的图标

您需要一个将 imageVectors 或 xml 文件转换为Path的库。 据我所知,没有内置库。 可能很少有转换成路径或形状的。

当你有一个形状或路径时,你需要做的是用这个形状作为修改器或画布

fun Modifier.vectorShadow(
    path: Path,
    x: Dp,
    y: Dp,
    radius: Dp
) = composed(
    inspectorInfo = {
        name = "vectorShadow"
        value = path
        value = x
        value = y
        value = radius
    },
    factory = {

        val paint = remember {
            Paint()
        }

        val frameworkPaint = remember {
            paint.asFrameworkPaint()
        }

        val color = Color.DarkGray
        val dx: Float
        val dy: Float
        val radiusInPx: Float

        with(LocalDensity.current) {
            dx = x.toPx()
            dy = y.toPx()
            radiusInPx = radius.toPx()
        }


        drawBehind {

            this.drawIntoCanvas {

                val transparent = color
                    .copy(alpha = 0f)
                    .toArgb()

                frameworkPaint.color = transparent

                frameworkPaint.setShadowLayer(
                    radiusInPx,
                    dx,
                    dy,
                    color
                        .copy(alpha = .7f)
                        .toArgb()
                )

                it.drawPath(path, paint)


            }
        }
    }
)

用法

Column(
    modifier = Modifier
        .fillMaxSize()
        .padding(8.dp)
) {

    val center = with(LocalDensity.current) {
        150.dp.toPx()
    }
    val path1 = createPolygonPath(center, center, 6, center)
    val path2 = createPolygonPath(center, center, 5, center)

    Canvas(
        modifier = Modifier
            .size(300.dp)
            .vectorShadow(path1, 0.dp, 0.dp, 6.dp)
            .border(3.dp, Color.Green)
    ) {
        drawPath(path1, Color.White)
    }
    Spacer(modifier = Modifier.height(10.dp))
    Canvas(
        modifier = Modifier
            .size(300.dp)
            .vectorShadow(path2, 3.dp, 3.dp, 10.dp)
            .border(3.dp, Color.Green)
    ) {
        drawPath(path2, Color.White)
    }
}

结果

在此处输入图像描述

createPolygonPath 是一个创建路径的示例函数。 如果您设法将矢量转换为路径,则其余部分很简单。

fun createPolygonPath(cx: Float, cy: Float, sides: Int, radius: Float): Path {
    val angle = 2.0 * Math.PI / sides

    return Path().apply {
        moveTo(
            cx + (radius * cos(0.0)).toFloat(),
            cy + (radius * sin(0.0)).toFloat()
        )
        for (i in 1 until sides) {
            lineTo(
                cx + (radius * cos(angle * i)).toFloat(),
                cy + (radius * sin(angle * i)).toFloat()
            )
        }
        close()
    }
}

这不完全是您想要的,但为了提升图标,您可以简单地执行以下操作:

Icon(
    Icons.Outlined.Refresh, contentDescription = "back",
    modifier = Modifier
        .size(300.dp)
        .offset(10.dp, 10.dp), tint = Color(0, 0, 0, 40)
)
Icon(
    Icons.Outlined.Refresh, contentDescription = "front",
    modifier = Modifier.size(300.dp), tint = Color(0xFFb6d7a8)
)

在此处输入图像描述

问题是它缺乏模糊效果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM