'How to make Dialog re-measure when a child size changes dynamically?

I implemented a simple dialog with Jetpack Compose on Android.

I am trying to show a caution message when isRehearsal is true.

The variable isRehearsal is toggled when the user clicks buttons, and changing button works fine when the user clicks the buttons and toggles isRehearal.

The problem is, that the caution text does not appear when the initial value of isRehearsal is false and later the variable becomes true. When I change the initial value of isRehearsal to true, then the text disappears/appears fine when isRehearsal becomes false or true.

var isRehearsal by remember { mutableStateOf(false) }
Dialog(
    onDismissRequest = { dismiss() },
    DialogProperties(dismissOnBackPress = true, dismissOnClickOutside = true)
) {
    Box(
        contentAlignment = Alignment.Center,
        modifier = Modifier
            .background(White, shape = RoundedCornerShape(8.dp))
            .fillMaxWidth()
            .padding(12.dp)
    ) { // the box does not resize when the caution text appears dynamically.
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.spacedBy(4.dp)
        ) {
            Text(text = "Set speed")
            Row(
                horizontalArrangement = Arrangement.SpaceEvenly,
                modifier = Modifier.fillMaxWidth()
            ) {
                if (isRehearsal) {
                    Button(
                        onClick = { isRehearsal = false },
                        colors = ButtonDefaults.buttonColors(
                            backgroundColor = Colors.Red400
                        )
                    ) {
                        Text(text = "Rehearsal ON")
                    }
                } else {
                    Button(
                        onClick = { isRehearsal = true },
                        colors = ButtonDefaults.buttonColors(
                            backgroundColor = Colors.Green400
                        )
                    ) {
                        Text(text = "Rehearsal OFF")
                    }
                }
                Button(onClick = { onClickStart(pickerValue) }) {
                    Text(text = "Start")
                }
            }
            if (isRehearsal) { // BUG!! when the intial value of isRehearsal is false, then the text never appears even when the value becomes true.
                Text(text = "Rehearsal does not count as high score") // <- The caution text
            }
        }
    }
}

How should I change the Box block to make the box's height extend properly to be able to wrap caution text when a view appears dynamically?

Edit If I change the catuion message part to like below, the text appears fine even when the initial value of isRehearsal is false. Therefore, I think that the issue is with the height of the Box composable.

if (isRehearsal) {
    Text(text = "Rehearsal does not count as high score")
} else {
    Spacer(modifier = Modifier.height(100.dp))
}


Solution 1:[1]

It looks like the topmost Dialog view size is not getting updated after the first recomposition. It's a known bug.

As a workaround until it's fixed, you can make a transparent topmost view take all the size available, and handle clicks same as dismissOnClickOutside option does:

Dialog(
    onDismissRequest = { },
) {
    Box(
        contentAlignment = Alignment.Center,
        modifier = Modifier
            .fillMaxSize()
            .clickable(
                interactionSource = remember { MutableInteractionSource() },
                indication = null,
            ) {
                // same action as in onDismissRequest
            }
    ) {
        // content
    }
}

Solution 2:[2]

You can use DialogProperties() with

usePlatformDefaultWidth = false

as a workaround. Example:

Dialog(
    onDismissRequest = {},
    properties = DialogProperties(usePlatformDefaultWidth = false)
) {
   Card(modifier = Modifier.padding(8.dp).wrapContentSize().animateContentSize()) {
        // content
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 adAAM91