Say that I have a button that expands when tapped the first time to reveal text, and performs an action on the second tap--thus acting as a sort of confirmation before performing the action.
@Compose
fun ExpandingConfirmButton(onConfirm: () -> Unit) {
// expanded state of the button
val (expanded, setExpanded) = remember { mutableStateOf(false) }
// animating weight. make the button larger when it is tapped once
val weight = animate(if (expanded) 10F else 2F)
Button(onClick = {
// only fire the action after two taps
if(expanded) {
onConfirm()
}
setExpanded(!expanded)
}) {
Icon(Icons.Dfault.Delete)
// only show the text if the button has already been clicked once,
// otherwise just show the icon
if(expanded) {
Text(text = "Delete", softWrap = false)
}
}
}
And I would use that button like so:
@Composable
fun PersonList(people: List<Person>) {
// some database service exposed via an ambient
val dataService = DataService.current
LazyColumnFor(items = people) {
Row() {
Text(text = it.firstName, modifier = Modifier.weight(10F))
// on the first tap, the button should take up half of the row
ExpandingConfirmButton(onConfirm = { dataService.deletePerson(it) })
}
}
}
This all seems pretty straight-forward. Indeed, before I had split the ExpandingConfirmButton
into it's own component and instead had the Button()
it wraps directly in my PersonList
component, it worked flawlessly.
However, it seems that the Row
doesn't quite know what to do with the button when the weight changes when it is inside it's own component. The text inside the button displays, but the size does not change. Does this have to do with the Row
's RowScope
not getting utilized by the Modifier
on the Button
component inside ExpandingConfirmButton
? If so, how do I go about using it?
What I ended up doing is basically just using the
.animateContentSize()
modifier.It really is just that easy. No messing with manual widths, weights, or anything like that.