Jetpack Compose 中的半椭圆形

Semi oval shape in Jetpack Compose

我正在尝试创建一个自定义的可选可组合项,对于选定的指示器,我希望在可组合项的末尾有一个圆角部分。最后的样子是这样的:

我目前拥有的是最后一个具有正确背景的框,我正在尝试在其之前添加另一个框作为圆角边缘。

问题是我试图在 clip 修饰符中使用 GenericShape 并使用 Path。我使用了 quadraticBezierTo 函数,但结果不是很好,因为顶部开始和底部开始边缘非常锋利。

我在 Compose 中寻找了一些椭圆形状,但我还没有找到我的运气。

这是我当前的实现:

@Composable
fun SelectableCard(
    information: @Composable RowScope.(modifier: Modifier) -> Unit,
    selected: Boolean = false
) {
    Card(
        modifier = Modifier
            .fillMaxWidth()
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .height(IntrinsicSize.Min)
        ) {
            information(
                modifier = Modifier
                    .padding(
                        vertical = dimensionResource(id = R.dimen.spacing_semi_small),
                        horizontal = dimensionResource(id = R.dimen.spacing_small),
                    )
            )
            // Selected indicator
            Box(
                modifier = Modifier
                    .fillMaxHeight()
                    .clip(
                        GenericShape { size, _ ->
                            val width: Float = size.width
                            val height: Float = size.height

                            // Starting point
                            moveTo(width, 0f)
                            quadraticBezierTo(
                                x1 = 0f,
                                y1 = height / 2,
                                x2 = width,
                                y2 = height
                            )
                        }
                    )
                    .background(Color.Red)
                    .width(20.dp)
            )
            Box(
                modifier = Modifier
                    .fillMaxHeight()
                    .width(60.dp)
                    .background(Color.Red),
            )
        }
    }
}

您可以使用 GenericShape 如:

class OvalCornerShape(
    size: Dp
) : Shape {

    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        val rect = size.toRect()
        val path = Path().apply {
            addOval(rect)
        }
        return Outline.Generic(path)
    }
}

并将其应用于 Box。类似于:

Box(
    modifier = Modifier
        .fillMaxWidth()
        .height(50.dp)
) {

    // Selected indicator
    Box(
        modifier = Modifier
            .offset(x= 10.dp)
            .fillMaxHeight()
            .width(60.dp)
            .background(Color.Red)

    )
    Box(
        modifier = Modifier
            .fillMaxHeight()
            .clip(OvalCornerShape(10.dp))
            .background(Color.Red)
            .width(20.dp)
    )

}