Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jetpack Compose Fullscreen Dialog

I tried to make a fullscreen dialog using Jetpack Compose using this code:

Dialog(onDismissRequest = { /*TODO*/ }) {
           NewPostDialog()
       }

It ended up looking something like this. How can I remove the margin at the side (marked red)?

Example

like image 645
Yannick Avatar asked Dec 10 '20 23:12

Yannick


3 Answers

UPDATE: As @Nestor Perez mentioned, since compose 1.0.0-rc01 you can set usePlatformDefaultWidthin DialogProperties to make a dialog fill the whole screenwidth:

Dialog(
    properties = DialogProperties(usePlatformDefaultWidth = false),
    onDismissRequest...
    ){
      Surface(modifier = Modifier.fillMaxSize()) {
          DialogContent()
      }
    }

Compose Dialog uses ContextThemeWrapper so you should be able to theme your dialog with a custom style.

themes.xml:

 <style name="Theme.YourApp" parent="Theme.MaterialComponents.Light.NoActionBar">
       //theme content...
        <item name="android:dialogTheme">@style/Theme.DialogFullScreen</item>
    </style>

 <style name="Theme.DialogFullScreen" parent="@style/ThemeOverlay.MaterialComponents.Dialog.Alert">
        <item name="android:windowMinWidthMajor">100%</item>
        <item name="android:windowMinWidthMinor">100%</item>
    </style>

And in code:

@Composable
fun FullScreenDialog(showDialog:Boolean, onClose:()->Unit) {
    if (showDialog) {
        Dialog(onDismissRequest =  onClose ) {
            Surface(
                modifier = Modifier.fillMaxSize(),
                shape = RoundedCornerShape(16.dp),
                color = Color.LightGray
            ) {
                Box(
                    contentAlignment = Alignment.Center
                ) {
                    Text(modifier = Modifier.align(Alignment.TopCenter),
                        text = "top")
                    Text("center")
                    Text(
                        modifier = Modifier.align(Alignment.BottomCenter),
                        text = "bottom")
                }
            }
        }
    }
}
like image 179
jns Avatar answered Oct 13 '22 16:10

jns


Solution from jns didnt work too well form me, I leave another solution here if anyone is still looking:

Implement the theme as jns answer:

<style name="Theme.Outlay" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    ...
    <!-- Customize your theme here. -->
    <item name="android:dialogTheme">@style/Theme.DialogFullScreen</item    >
</style>

<style name="Theme.DialogFullScreen" parent="@style/ThemeOverlay.MaterialComponents.Dialog.Alert">
    <item name="android:windowMinWidthMajor">100%</item>
    <item name="android:windowMinWidthMinor">100%</item>
</style>

For the dialog create an scaffold and add the experimental property "usePlatformDefaultWidth = false" on dialog properties:

Dialog(
    onDismissRequest = onBackPressed,
    properties = DialogProperties(
        usePlatformDefaultWidth = false
    )
) {
    Scaffold(topBar = { TopBar(onBackPressed = onBackPressed) }) {
        Content()
    }
}
like image 45
Nestor Perez Avatar answered Oct 13 '22 18:10

Nestor Perez


If you want to avoid having an xml theme entirely and also avoid doing this for all dialogs, you can set a requiredWidth modifier to be equal to LocalConfiguration.current.screenWidthDp.dp (multiplied by some fraction as you please).

An example that takes up 0.96f of the screen width:

@Composable
fun LargerDialog(
    dialogOpen: MutableState<Boolean>
) {
    Dialog(onDismissRequest = { dialogOpen.value = false }) {
        Card( // or Surface
            elevation = 8.dp,
            modifier = Modifier
                .requiredWidth(LocalConfiguration.current.screenWidthDp.dp * 0.96f)
                .padding(4.dp)
        ) {
            // content
        }
    }
}
like image 37
Can_of_awe Avatar answered Oct 13 '22 17:10

Can_of_awe