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.
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.
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)
)
}
}
The content of a Button
is a RowScope
.Just apply a weight(1f)
modifier to the Text
together with TextOverflow.Ellipsis
.
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
)
}