Home > Enterprise >  Jetpack Compose custom Badge with dynamic text size with CircleShape is not drawn correctly
Jetpack Compose custom Badge with dynamic text size with CircleShape is not drawn correctly

Time:11-17

I had a BadgeView written with View using onMeasure, onLayout and OnDraw

enter image description here

I'm trying to migrate enter image description here

Then tried using

var size: Dp by remember { mutableStateOf(40.dp) }

val density = LocalDensity.current

Surface(
    shape = CircleShape,
    modifier = Modifier.size(size),
    contentColor = Color.Yellow,
    color = Color.Red
){
    Text(
        text = "0",
        modifier = Modifier.padding(4.dp),
        fontSize = 24.sp,
        onTextLayout = { textLayoutResult: TextLayoutResult ->
            val textSize = textLayoutResult.size
            val circleRadius = textSize.width.coerceAtLeast(textSize.height)

            size = with(density) {
                circleRadius.toDp()
            }
            
            println("Size: $size")
        }
    )
}

Both of the implementations are not working, then tried doing it with Layout

@Composable
private fun Badge(text: String, badgeState: BadgeState, modifier: Modifier = Modifier) {
    Surface(shape = CircleShape, color = Color.Red, contentColor = Color.White) {
        BadgeLayout(text = text, badgeState = badgeState, modifier = modifier)
    }
}

@Composable
private fun BadgeLayout(text: String, badgeState: BadgeState, modifier: Modifier = Modifier) {

    var circleRadius = 0
    var size: IntSize by remember {
        mutableStateOf(IntSize(0, 0))
    }

    val content = @Composable {

        Text(
            text = text,
            modifier = Modifier.padding(4.dp),
            fontSize = 34.sp,
            onTextLayout = { textLayoutResult: TextLayoutResult ->
                size = textLayoutResult.size
                circleRadius = size.width.coerceAtLeast(size.height)
            },
        )

    }

    Layout(
        modifier = modifier,
        content = content
    ) { measurables: List<Measurable>, constraints: Constraints ->

        val placeables = measurables.map { measurable ->
            measurable.measure(constraints)
        }

        println("           
  • Related