Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AnimatedVisibility Doesn't Expand Height In Dialog in Jetpack Compose

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.

like image 310
AgentP Avatar asked Dec 05 '25 17:12

AgentP


2 Answers

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.

like image 83
AgentP Avatar answered Dec 08 '25 06:12

AgentP


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)
                )
            }
        }
    }
}
like image 27
Philip Dukhov Avatar answered Dec 08 '25 08:12

Philip Dukhov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!