如何将具有固定值的路径缩放为动态可组合大小?

Ric*_*per 2 android android-jetpack-compose

我有一个简单的Box可组合项,我想将其剪辑为自定义形状,但每当我尝试它时,形状的大小仍然非常僵硬且很小。我尝试使用在路径级别上进行缩放Matrix(),但无济于事。这是示例 -

const val clockHand = "M0 80.52L2 86l2-5.48V2.74C4 1.83 3.6 0 2 0S0 1.83 0 2.74v77.78Z"
val clockHandShape = object : Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        return Outline.Generic(PathParser.createPathFromPathData(clockHand).asComposePath())
    }
}

Box(
                        modifier = Modifier
                            .background(Color.Green)
                            .clip(clockHandShape)
                            .width(30.dp)
                            .height(50.dp)
                            .background(Color(0xFFFF007A))
                            .layoutId("hourHand")
) {}
Run Code Online (Sandbox Code Playgroud)

作为一种控件,您可以用预定义的形状替换自定义形状,例如RectangleShapeCircleShape

Thr*_*ian 5

剪切不会使尺寸修改器失效。形状是使用来自创建该可绘制对象的值的固有像素大小创建的。

您需要做的就是使用 getBounds().size 获取 Path 的内在大小,并在使用 Matrix.postScale 创建形状时缩放到可组合大小。

@Preview
@Composable
private fun Test() {

    val clockHand = "M0 80.52L2 86l2-5.48V2.74C4 1.83 3.6 0 2 0S0 1.83 0 2.74v77.78Z"
    val path = PathParser.createPathFromPathData(clockHand).asComposePath()
    val pathSize = path.getBounds().size

    val clockHandShape = object : Shape {
        override fun createOutline(
            size: Size,
            layoutDirection: LayoutDirection,
            density: Density
        ): Outline {

            val matrix = android.graphics.Matrix()
            matrix.postScale(
                size.width / pathSize.width, size.height / pathSize.height
            )
            path.asAndroidPath().transform(matrix)

            return Outline.Generic(path)
        }
    }

    Box(
        modifier = Modifier
            .clip(clockHandShape)
            .size(90.dp, 150.dp)
            .background(Color(0xFFFF007A))
            .layoutId("hourHand")
    ) {}
}
Run Code Online (Sandbox Code Playgroud)