如何使用 Jetpack Compose 实现侧面带有半圆夹的自定义形状?

问题描述 投票:0回答:1

所以我需要在 Jetpack Compose 中实现类似的形状

enter image description here

我正在尝试使用以下代码,但目前没有运气:

fun clippedCardShape(clipRadius: Float = 30f): Shape {
    return object : Shape {
        override fun createOutline(
            size: androidx.compose.ui.geometry.Size,
            layoutDirection: LayoutDirection,
            density: Density
        ): Outline {
            val path = Path().apply {
                // Top line
                lineTo(size.width, 0f)

                // Right side clipping
                lineTo(size.width, size.height / 2 - clipRadius)
                arcTo(
                    rect = Rect(
                        left = size.width - clipRadius * 2,
                        top = size.height / 2 - clipRadius,
                        right = size.width,
                        bottom = size.height / 2 + clipRadius
                    ),
                    startAngleDegrees = 270f,
                    sweepAngleDegrees = -180f,
                    forceMoveTo = false
                )

                lineTo(size.width, size.height)

                // Bottom line
                lineTo(0f, size.height)

                // Left side clipping
                lineTo(0f, size.height / 2 + clipRadius)
                arcTo(
                    rect = Rect(
                        left = 0f,
                        top = size.height / 2 - clipRadius,
                        right = clipRadius * 2,
                        bottom = size.height / 2 + clipRadius
                    ),
                    startAngleDegrees = 90f,
                    sweepAngleDegrees = 180f,
                    forceMoveTo = false
                )
                lineTo(0f, 0f)

                close()
            }
            return Outline.Generic(path)
        }
    }
}

代码尝试在中间添加剪切,但它应该几乎位于形状的顶部,如示例图像所示。

结果:

enter image description here

因此,我希望看到知道如何处理它的人提供的工作示例,以便我可以学习它并找出如何在不同情况下实现类似形状的逻辑和数学。

android android-jetpack-compose android-custom-view
1个回答
0
投票

你可以这样做:

@Composable
fun ClippedCardShape() {
    Scaffold { paddingValues ->
        Column(
            Modifier
                .padding(paddingValues)
                .background(Color(0xFF426695))
                .background(Color.Black, clippedCardShape())
        ) {
            Spacer(Modifier.fillMaxWidth().height(300.dp))
        }
    }
}

fun clippedCardShape(clipRadius: Float = 60f, clipPosition: Float = 0.2f): Shape =
    object : Shape {
        override fun createOutline(
            size: androidx.compose.ui.geometry.Size,
            layoutDirection: LayoutDirection,
            density: Density
        ): Outline {
            val path = Path().apply {
                addOval(
                    oval = Rect(
                        left = size.width - clipRadius,
                        top = size.height * clipPosition - clipRadius,
                        right = size.width + clipRadius,
                        bottom = size.height * clipPosition + clipRadius
                    )
                )
                addOval(
                    oval = Rect(
                        left = -clipRadius,
                        top = size.height * clipPosition - clipRadius,
                        right = clipRadius,
                        bottom = size.height * clipPosition + clipRadius
                    )
                )
            }
            return Outline.Generic(path)
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.