What is the purpose of the PaddingValues parameter in a Scaffold

24.7k Views Asked by At
@Composable
fun LayoutsCodelab() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Text(text = "LayoutsCodelab")
                }
            )
        }
    ) { innerPadding ->
        BodyContent(Modifier.padding(innerPadding))
    }
}

Removing innerPadding does not change anything.

Please note, I am new to Compose.
if you have any confusion, please ask in comments

2

There are 2 best solutions below

9
On BEST ANSWER

The padding values provided to your content are only set if you set the bottomBar parameter. This unfortunately is not documented. If you set the bottomBar, the Scaffold will set the bottom padding of PaddingValues to be the height of the content that the bottomBar content uses. The other padding values (start, top, end) are currently set to zero. Not sure if that will change in the future.

Providing the bottom padding is useful if your content contains a scrollable list and you want to offset the bottom of the list by the height of the bottomBar content. If you don't include any bottomBar content, the PaddingValues will always remain set to zero.

Here is an example that shows how the PaddingValues parameter is passed into your content when the bottomBar uses a BottomAppBar. It displays a list of 50 items. When the padding is added to the Column, you can scroll to the bottom and see the last item. If you remove the Column's padding and repeat the test, when you scroll to the bottom, the last several items are not visible because the Column extends all the way to the bottom of the scaffold without any bottom padding and the bottom app bar covers those last items:

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

        startActivity(intent)

        setContent {

            Scaffold(
                topBar = {
                    TopAppBar(
                        title = {
                            Text(text = "Padding values in a scaffold")
                        }
                    )
                },
                bottomBar = {
                    BottomAppBar() {
                        CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
                            IconButton(onClick = { /* doSomething() */ }) {
                                Icon(Icons.Filled.Menu, contentDescription = "Localized description")
                            }
                        }
                        Spacer(Modifier.weight(1f, true))
                        IconButton(onClick = { /* doSomething() */ }) {
                            Icon(Icons.Filled.Favorite, contentDescription = "Localized description")
                        }
                        IconButton(onClick = { /* doSomething() */ }) {
                            Icon(Icons.Filled.Favorite, contentDescription = "Localized description")
                        }
                    }
                }
            ) { paddingValues ->
                Column(modifier = Modifier
                    .fillMaxSize()
                    .padding(bottom = paddingValues.calculateBottomPadding())
                    .verticalScroll(rememberScrollState())) {

                    Text("Bottom app bar padding:  $paddingValues")

                    repeat(50) {
                        Text(it.toString())
                    }
                }
            }
        }
    }
}

I can't understand why Google would not include the top padding. After all, if the top app bar is included, it also takes up space. I think the reason has to do with collapsing top bars. If the top app bar collapses while scrolling, the content area needs to expand - so adding padding to the top may not make sense. It does make sense though if the top app bar remains fixed.

0
On

As per documentation

content lambda receives an instance of PaddingValues that should be applied to the content root — for example, via Modifier.padding — to offset the top and bottom bars, if they exist.