Home > Mobile >  How to achieve the following layout in Compose
How to achieve the following layout in Compose

Time:01-15

enter image description here

I want to design a layout like this in Compose. In my case both the components have a variable width. But I still want the title to be centered and the icon to be right aligned.

I tried using Row but if the title or the button changes, alignment becomes unstable.

Row(
 modifier = Modifier.fillMaxWidth(),
 verticalAlignment = Alignment.CenterVertically,
 horizontalArrangement = Arrangement.SpaceBetween
 ){
   Spacer(modifier = Modifier.width(1.dp))
   Text("Title Comes here")
   TextButton(onClick = { }) { Text(text = "Dynamic Button") }
}

CodePudding user response:

You can use a Box instead of a Row

Box(
    modifier = Modifier.fillMaxWidth(),
    contentAlignment = Alignment.Center,
){
    Text(
        text = "Title Comes here",
        modifier = Modifier.fillMaxWidth(),
        textAlign = TextAlign.Center
    )

    TextButton(
        onClick = { },
        modifier = Modifier.align(CenterEnd)
    ){
        Text(text = "Button")
    }
}

enter image description here

If you have a more complex logic you can use the Layout composable:

Layout(
    content = {
        //Title
        Text(text = "Title Comes here")

        //TextButton or IconButton
        TextButton(onClick = { } ){
            Text(text = "Button")
        }
        IconButton(onClick = { } ){
            Icon(Icons.Filled.Add,"contentButton")
        }
    },
    measurePolicy = { measurables, constraints ->
        val title = measurables[0].measure(constraints)
        val textButton = measurables[1].measure(constraints)
        val iconButton = measurables[2].measure(constraints)

        val endPadding = 8.dp.toPx().toInt()

        //Use your custom logic
        //If the title   text button are overlapping the TextButton is replaced by a IconButton
        var isOverlapping = false
        if (title.width/2   textButton.width > constraints.maxWidth/2)
            isOverlapping = true

        val height = maxOf(
            if (isOverlapping) iconButton.height else textButton.height,
            title.height,
            constraints.minHeight)

        layout(
            width = constraints.maxWidth,
            height = height
        ) {
            title.placeRelative(
                constraints.maxWidth/2 - title.width/2,
                height/2-title.height/2)

            if (isOverlapping)
                iconButton.placeRelative(
                    constraints.maxWidth - iconButton.width - endPadding,
                    height/2-iconButton.height/2)
            else
                textButton.placeRelative(
                    constraints.maxWidth - textButton.width - endPadding,
                    height/2-textButton.height/2)


        }

    }
)

enter image description here

  • Related