[英]How to add a shadow / border / elevation to an icon in 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.