recalculateWindowInsets
Functions summary
Modifier |
This recalculates the |
Cmn
|
Functions
Modifier.recalculateWindowInsets
fun Modifier.recalculateWindowInsets(): Modifier
This recalculates the WindowInsets based on the size and position. This only works when Constraints have fixed width and fixed height. This can be accomplished, for example, by having Modifier.size, or Modifier.fillMaxSize, or other size modifier before recalculateWindowInsets. If the Constraints sizes aren't fixed, recalculateWindowInsets won't adjust the WindowInsets and won't have any affect on layout.
recalculateWindowInsets is useful when the parent does not call consumeWindowInsets when it aligns a child. For example, a Column with two children should have different WindowInsets for each child. The top item should exclude insets below its bottom and the bottom item should exclude the top insets, but the Column can't assign different insets for different children.
import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.recalculateWindowInsets import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.material.Button import androidx.compose.material.Text import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color var hasFirstItem by remember { mutableStateOf(true) } var hasLastItem by remember { mutableStateOf(true) } Column(Modifier.fillMaxSize()) { if (hasFirstItem) { Box(Modifier.weight(1f).fillMaxWidth().background(Color.Magenta)) } Box( Modifier.fillMaxWidth() // force a fixed size on the content .recalculateWindowInsets() .weight(1f) .background(Color.Yellow) .safeDrawingPadding() ) { Button( onClick = { hasFirstItem = !hasFirstItem }, Modifier.align(Alignment.TopCenter), ) { val action = if (hasFirstItem) "Remove" else "Add" Text("$action First Item") } Button( onClick = { hasLastItem = !hasLastItem }, Modifier.align(Alignment.BottomCenter), ) { val action = if (hasLastItem) "Remove" else "Add" Text("$action Last Item") } } if (hasLastItem) { Box(Modifier.weight(1f).fillMaxWidth().background(Color.Cyan)) } }
Another use is when a parent doesn't properly consumeWindowInsets for all space that it consumes. For example, a 3rd-party container has padding that doesn't properly use consumeWindowInsets.
import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.recalculateWindowInsets import androidx.compose.foundation.layout.safeContent import androidx.compose.foundation.layout.safeContentPadding import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp // This outer Box is representing a 3rd-party layout that you don't control. It has a // padding, but doesn't properly use consumeWindowInsets() Box(Modifier.padding(10.dp)) { // This is the content that you control. You can make sure that the WindowInsets are correct // so you can pad your content despite the fact that the parent did not // consumeWindowInsets() Box( Modifier.fillMaxSize() // Force a fixed size on the content .recalculateWindowInsets() .safeContentPadding() .background(Color.Blue) ) }
In most cases you should not need to use this API, and the parent should instead use consumeWindowInsets to provide the correct values
import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeContent import androidx.compose.foundation.layout.safeContentPadding import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp // The outer Box uses padding and properly compensates for it by using consumeWindowInsets() Box( Modifier.fillMaxSize() .padding(10.dp) .consumeWindowInsets(WindowInsets(10.dp, 10.dp, 10.dp, 10.dp)) ) { Box(Modifier.fillMaxSize().safeContentPadding().background(Color.Blue)) }