So I have this composable in my project ...
@Composable
private fun ShowDialog() {
var showText by remember { mutableStateOf(false) }
val text = if (showText) {
"Hide Text"
} else {
"Show Text"
}
Dialog(onDismissRequest = { }) {
Card(modifier = Modifier.padding(15.dp)) {
Column(modifier = Modifier.padding(15.dp)) {
AnimatedVisibility(visible = showText) {
Text(
text = "Here is the show text sample",
modifier = Modifier.padding(5.dp),
style = MaterialTheme.typography.body1,
color= Color.Black
)
}
Button(onClick = { showText = !showText }) {
Text(text = text)
}
}
}
}
}
If you have gone through the code, you might get what it is supposed to do. i.e it is basically a dialog with one text and a button below it. When the user clicks on a button the text above the button will toggle its visibility.
But the problem with the code is, When I click on the button, the text appears but the button gets invisible in other words the text takes the space and pushes a button to below. But yet the container in this case card or the column doesn't expand its height.
Is it supposed to work like that ? Or is this a bug?
I tried animateContentSize() on Column and Card but it didn't work. And checked similar questions on StackOverflow but didn't found any useful information.
Luckily, I found a temporary working answer for this problem,
What we need to use is just pass DialogProperties(usePlatformDefaultWidth = false) as properties parameter for dialog. This will make the dialog to resizable like this
@Composable
private fun ShowDialog() {
var showText by remember { mutableStateOf(false) }
val text = if (showText) {
"Hide Text"
} else {
"Show Text"
}
Dialog(
onDismissRequest = { },
properties = DialogProperties(usePlatformDefaultWidth = false)
) {
Card(
modifier = Modifier
.padding(15.dp)
.wrapContentWidth()
.animateContentSize()
) {
Column(modifier = Modifier.padding(15.dp).fillMaxWidth(1f)) {
AnimatedVisibility(visible = showText) {
Text(
text = "Sample",
modifier = Modifier
.padding(5.dp)
.fillMaxWidth(1f),
style = MaterialTheme.typography.body1,
color = Color.Black
)
}
Button(onClick = { showText = !showText }) {
Text(text = text)
}
}
}
}
}
Caution: It uses @ExperimentalComposeUiApi
This API is experimental and is likely to change in the future.
If you need to have the default platform width and cannot use usePlatformDefaultWidth = false, here is another workaround until the bug is fixed:
@Composable
fun DynamicHeightDialog(
onDismissRequest: () -> Unit,
properties: DialogProperties = DialogProperties(),
content: @Composable () -> Unit,
) {
Dialog(
onDismissRequest = onDismissRequest,
properties = properties,
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxHeight()
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
onClick = onDismissRequest,
)
) {
content()
}
}
}
Usage example:
var opened by rememberSaveable { mutableStateOf(true) }
Switch(
checked = opened,
onCheckedChange = { opened = it },
)
if (opened) {
DynamicHeightDialog(
onDismissRequest = {
opened = false
}
) {
Surface {
Column() {
var expanded by rememberSaveable { mutableStateOf(false) }
val height by animateDpAsState(if (expanded) 100.dp else 20.dp)
Switch(
checked = expanded,
onCheckedChange = { expanded = it },
)
Box(
modifier = Modifier
.height(height)
)
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With