![](/img/trans.png)
[英]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.