Home > other >  How to use weight in a layout that wraps to its content in Jetpack Compose
How to use weight in a layout that wraps to its content in Jetpack Compose

Time:08-24

I'm building a re-usable Button component in Jetpack Compose, which is basically a Row. The button should have a text on the left end and an icon on the right end. This works straight forward like this:

@Composable
fun MyButton(
    text: String,
    modifier: Modifier = Modifier
) {
    Button(
        onClick = { /* */ },
        modifier = modifier
    ) { // RowScope
        Text(
            text = text
        )
        Spacer(modifier = Modifier.width(8.dp))
        Icon(
            painter = painterResource(
                id = android.R.drawable.ic_dialog_info
            ),
            contentDescription = null
        )
    }
}

However, if the button gets applied a fixed width, the text & icon is centered and not at the left/right end.

enter image description here

So I tried adding modifier = Modifier.weight(1F) to the Text so it fills up any additional space. But this causes a button without a fixed width to take up as much space as it can.

enter image description here

How can I build a Compose component that works in both cases: When a width is defined and when it is wrap-to-content?

My screen layout:

@Composable
fun MyScreen() {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.fillMaxSize()
    ) {
        Spacer(modifier = Modifier.height(8.dp))
        MyButton(
            text = "variable width",
            modifier = Modifier.wrapContentWidth()
        )
        Spacer(modifier = Modifier.height(8.dp))
        MyButton(
            text = "fixed width",
            modifier = Modifier.width(300.dp)
        )
    }
}

CodePudding user response:

You can use something like:

Button(
    onClick = { /* */ },
    modifier = modifier.width(IntrinsicSize.Max)
) { // RowScope
    Text(
        text = text,
        maxLines = 1,
        modifier = Modifier.weight(1f),
        overflow = TextOverflow.Ellipsis
    )
    Spacer(modifier = Modifier.width(8.dp))
    Icon(
        painter = painterResource(
            id = android.R.drawable.ic_dialog_info
        ),
        contentDescription = null
    )
}

enter image description here

CodePudding user response:

I believe you need to set an intrinsic width on your Button. Something like

Button(
        onClick = { /* */ },
        modifier = modifier.width(IntrinsicSize.Min)
    )

See the documentation here, https://developer.android.com/jetpack/compose/layouts/intrinsic-measurements

  • Related