Jetpack Compose UI - Button width changes on click inside AlertDialog

701 views Asked by At

I'm facing this weird issue with fillMaxWidth(fraction = ...) with an AlertDialog and Button, where the Button shows up initially at one size, and on click it shrinks to wrapping its content. Here is the most basic example I can create. I've tried with multiple versions of Compose but they all do the same thing. Any ideas?

AlertDialog(
    modifier = modifier,
    onDismissRequest = {},
    text = { },
    buttons = {
        Button(
            onClick = { },
            modifier = Modifier
                .fillMaxWidth(0.75f)
                .padding(start = 12.dp, end = 12.dp, bottom = 8.dp)
            ) {
                Text(text = "Done")
            }
        }
    )

Before click:

Button fills size of AlertDialog

After click:

Button's width has shrunk

2

There are 2 answers

0
z.g.y On BEST ANSWER

I think you have to define a specific width for the AlertDialog, any child it has may not be able to calculate a 75% of unknown width .

either you fill the max width of the dialog

 AlertDialog(
       modifier = Modifier.fillMaxWidth(),
       ...

enter image description here

or specify an actual dp width

AlertDialog(
    modifier = Modifier.width(150.dp),
    ...

enter image description here

I don't wanna throw jargons I can't explain, but I suspect when AlertDialog doesn't have any specific width, it cannot provide any incoming measurements for its children, which is in this case the Button cannot compute a 75% of unknown width on initial display, it looks like all size computation is happening only after an action has been made to the button, maybe a recomposition is happening under-the-hood having correct measurements.

0
Chris On

I've used the sample composable from here and added your modifier to it for each button so it looks like

@Composable
fun AlertDialogSample() {
    MaterialTheme {
        Column {
            val openDialog = remember { mutableStateOf(false) }

            Button(onClick = {
                openDialog.value = true
            }) {
                Text("Click me")
            }

            if (openDialog.value) {

                AlertDialog(
                    onDismissRequest = {
                        // Dismiss the dialog when the user clicks outside the dialog or on the back
                        // button. If you want to disable that functionality, simply use an empty
                        // onCloseRequest.
                        openDialog.value = false
                    },
                    title = {
                        Text(text = "Dialog Title")
                    },
                    text = {
                        Text("Here is a text ")
                    },
                    confirmButton = {
                        Button(
                            modifier = Modifier
                                .fillMaxWidth(0.75f)
                                .padding(start = 12.dp, end = 12.dp, bottom = 8.dp),
                            onClick = {
                                openDialog.value = false
                            }) {
                            Text("This is the Confirm Button")
                        }
                    },
                    dismissButton = {
                        Button(
                            modifier = Modifier
                                .fillMaxWidth(0.75f)
                                .padding(start = 12.dp, end = 12.dp, bottom = 8.dp),
                            onClick = {
                                openDialog.value = false
                            }) {
                            Text("This is the dismiss Button")
                        }
                    }
                )
            }
        }

    }
}

and I see the buttons at 75% width.

Doesn't explain why you see the described issue, but does give you a solution.