简体   繁体   中英

Semi oval shape in Jetpack Compose

I am trying to create a custom selectable composable and for the selected indicator, I would like to have a section at the end of the composable with a rounded edge. The final look would be something like this:

复选标记

What I have currently is a box at the end with the correct background and I am trying to have another box just before which will act as the rounded edge.

The issue is that I am trying to use a GenericShape within the clip modifier and play with the Path . I have use a quadraticBezierTo function but the result isn't great since the top start and bottom start edges are very sharp.

I have looked for some Oval shap in Compose but I haven't found my luck yet.

Here is my current implementation:

@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),
            )
        }
    }
}

You can use a GenericShape like:

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)
    }
}

and apply it to the Box . Something like:

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)
    )

}

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM