7

I am having an android activity which has Base.Theme.AppCompat.Light.Dialog as a theme on tablets and therefore is shown in a dialog.

When I used XML layouts I could set a min height with wrap content for the layout so it would

  • Be at least x dp high when there was no or very little content.
  • High as the content when the content was higher than the min height
  • High as the screen when the content wouldnt fit inside the height of the screen, in that case I could scroll

Using a Jetpack Compose's Scaffold I am struggling recreating that behaviour. The dialog is alsways as high as the screen allows, even when there is no content.

I tried the following modifiers as a parameter to the scaffold:

  • Modifier.wrapContentHeight() - the dialog is still as high as the screen
  • Modifier.defaultMinSize(minHeight = 250.dp) - the dialog is still as high as the screen
  • Modifier.height(height = 250.dp) - now it is smaller but it is fixed to that size, not growing when there is more content
  • Modifier.requiredHeightIn(min = 250.dp, max = getMyScreenHeightinDp()) - the dialog is still as high as the screen

Since you can reduce the height of the scaffold with the .height(...) modifier I think it should also be possible to recreate a wrap content behaviour. But how?

Henning
  • 2,202
  • 1
  • 17
  • 38

2 Answers2

1

Using requiredHeightIn does work, as tested in the code below. In this list, the height varies from 150.dp to 400.dp. If you only provide 10 items, it will be 150.dp. As you add more items, it increases in height but only to a maximumo of 400.dp.

However, there is a catch. The navigation drawer slides out from the left side of the screen and not the left side of the dialog. There are ways around that. You could replace the navigation drawer with your own custom drawer. I did this once and it can be done.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        startActivity(intent)

        setContent {

            Dialog(
                onDismissRequest = {  },
                properties = DialogProperties(dismissOnClickOutside = false)
            ) {
                val scaffoldState = rememberScaffoldState()
                val scope = rememberCoroutineScope()
                Scaffold(
                    modifier = Modifier.requiredHeightIn(min = 150.dp, max = 400.dp),
                    scaffoldState = scaffoldState,
                    drawerContent = { Text("Drawer content") },
                    topBar = {
                        TopAppBar(
                            title = { Text("Simple Scaffold Screen") },
                            navigationIcon = {
                                IconButton(
                                    onClick = {
                                        scope.launch { scaffoldState.drawerState.open() }
                                    }
                                ) {
                                    Icon(Icons.Filled.Menu, contentDescription = "Localized description")
                                }
                            }
                        )
                    },
                    floatingActionButtonPosition = FabPosition.End,
                    floatingActionButton = {
                        ExtendedFloatingActionButton(
                            text = { Text("Inc") },
                            onClick = { /* fab click handler */ }
                        )
                    },
                    content = { innerPadding ->
                        LazyColumn(contentPadding = innerPadding) {
                            items(count = 100) {
                                Text(it.toString())

                            }
                        }
                    }
                )
            }
        }
    }
}
Johann
  • 27,536
  • 39
  • 165
  • 279
  • 1
    Thanks for your answer. Sadly I must report that your solution does not work for me. I created a new project and pasted your code. Set the max height to 800 dp and one list item to 25 dp and displayed 8 list items. The dialog is four times as high as the list goes: https://imgur.com/a/C6B8yK5 – Henning Dec 09 '21 at 15:01
0

You can set the height based on percentage in your modifier.

.fillMaxHeight(0.90f)

Marty Miller
  • 913
  • 2
  • 11
  • 27
  • I won't recommend to do this for Adaptative views, for example on smaller screens, or in Landscape orientation. – Joe Mama Jr. Mar 31 '23 at 15:04
  • 1
    The question was how to make the scaffold not to take up the whole screen. This code does that based on the percentage height of the screen (and not a specific dp value). Whether you want to do this for smaller screens or landscape mode is a different issue. – Marty Miller Apr 01 '23 at 19:58