我将 material icon 存储在数据类中,如下所示:
import androidx.compose.ui.graphics.vector.ImageVector
data class Item(
val icon: ImageVector
)
val item = Item(Icons.Filled.Send)
该项目稍后会传递到可组合项,并使用
VectorPainter
进行绘制。
如何将
ImageVector
旋转 90 度?理想情况下,这会产生一个 ImageVector
,我仍然可以将其存储在数据类中。
正如我从评论中得到的那样,您的 Composable 没有修饰符参数,这不是一个好的设计。每个可组合项即使您不会立即使用它,也应该始终有一个修饰符参数。
https://chrisbanes.me/posts/always-provide-a-modifier/
在过去一年左右的时间里,我看到了很多看起来像的可组合项 很棒,但它们有一个致命的缺陷:它们没有公开修饰符: 签名中的修饰符参数。
如果您不想阅读整篇文章,请阅读这篇博文的 TL;DR 是:
您编写的任何发出布局的可组合项(甚至是一个简单的 Box), 应该有一个修饰符:Modifier 参数,然后在 布局。
即使可组合项没有修饰符参数,您也可以先将旋转参数添加到
Item
数据类
data class Item(
val icon: ImageVector,
val rotation: Float
)
然后用
包装没有 Modifier 参数的 ComposableBox(modifier = Modifier.rotate(item.rotation) {
// Your Composable here
}
imageVector.root.rotation
将 rotation
公开为不可变参数,您无法更改该参数,也无法公开 IconVector 的路径,如果这是原因,则可以通过矩阵进行旋转。
public val Icons.Filled.Send: ImageVector
get() {
if (_send != null) {
return _send!!
}
_send = materialIcon(name = "Filled.Send") {
materialPath {
moveTo(2.01f, 21.0f)
lineTo(23.0f, 12.0f)
lineTo(2.01f, 3.0f)
lineTo(2.0f, 10.0f)
lineToRelative(15.0f, 2.0f)
lineToRelative(-15.0f, 2.0f)
close()
}
}
return _send!!
}
private var _send: ImageVector? = null
您可以构建一个旋转的
ImageVector
,从源 ImageVector
复制所有组和路径,并应用所需的旋转参数(与确定旋转中心点的 pivotX
/pivotY
的正确值相结合)。
fun ImageVector.Companion.copyFrom(
src: ImageVector,
rotation: Float = src.root.rotation,
pivotX: Float = src.root.pivotX,
pivotY: Float = src.root.pivotY,
) = ImageVector.Builder(
name = src.name,
defaultWidth = src.defaultWidth,
defaultHeight = src.defaultHeight,
viewportWidth = src.viewportWidth,
viewportHeight = src.viewportHeight,
tintColor = src.tintColor,
tintBlendMode = src.tintBlendMode,
autoMirror = src.autoMirror,
).addGroup(
src = src.root,
rotation = rotation,
pivotX = pivotX,
pivotY = pivotY,
).build()
private fun ImageVector.Builder.addNode(node: VectorNode) {
when (node) {
is VectorGroup -> addGroup(node)
is VectorPath -> addPath(node)
}
}
private fun ImageVector.Builder.addGroup(
src: VectorGroup,
rotation: Float = src.rotation,
pivotX: Float = src.pivotX,
pivotY: Float = src.pivotY,
) = apply {
group(
name = src.name,
rotate = rotation,
pivotX = pivotX,
pivotY = pivotY,
scaleX = src.scaleX,
scaleY = src.scaleY,
translationX = src.translationX,
translationY = src.translationY,
clipPathData = src.clipPathData,
) {
src.forEach { addNode(it) }
}
}
private fun ImageVector.Builder.addPath(src: VectorPath) = apply {
addPath(
pathData = src.pathData,
pathFillType = src.pathFillType,
name = src.name,
fill = src.fill,
fillAlpha = src.fillAlpha,
stroke = src.stroke,
strokeAlpha = src.strokeAlpha,
strokeLineWidth = src.strokeLineWidth,
strokeLineCap = src.strokeLineCap,
strokeLineJoin = src.strokeLineJoin,
strokeLineMiter = src.strokeLineMiter,
)
}
用法可以如下所示:
val icon = ImageVector.vectorResource(R.drawable.ic_smile)
val rotatedIcon = ImageVector.copyFrom(
src = icon,
rotation = 90f,
pivotX = icon.defaultWidth.value / 2,
pivotY = icon.defaultHeight.value / 2,
)
您可以使用“ImageVector”类提供的“旋转”方法。例如:
data class Item(
val icon: ImageVector
)
val item = Item(Icons.Filled.Send.rotate(90f))