I have a screen with a NavigationBar and a content screen with a TextField as follow:
+-------------------------------+
| |
| Content Composable |
| |
| _____________________ |
| | | |
| | TextField | |
| |_____________________| |
| |
| |
| |
+----------+----------+---------+
| Home | Search | Profile |
+----------+----------+---------+
Column {
Column(Modifier.verticalScroll().weight(1f)) {
...
TextField(...)
}
NavigationBar { ... }
}
If I apply .imePadding()
modifier to the inner Column, the bottom padding would be too large as it doesn't compensate for the NavigationBar and bottom system bar. How do I subtract the height of the navigation bar and bottom system bar from this IME padding?
WindowInsets subtraction can be done with .consumeWindowInsets(PaddingValues(...))
.
I wrote the following modifier that adjusts the padding depending on how far composable is from the bottom of the window:
fun Modifier.positionAwareImePadding() = composed {
var consumePadding by remember { mutableStateOf(0) }
onGloballyPositioned { coordinates ->
val rootCoordinate = coordinates.findRootCoordinates()
val bottom = coordinates.positionInWindow().y + coordinates.size.height
consumePadding = (rootCoordinate.size.height - bottom).toInt()
}
.consumeWindowInsets(PaddingValues(bottom = (consumePadding / LocalDensity.current.density).dp))
.imePadding()
}
Example usage in OP's scenario:
Column {
Column(modifier = Modifier
.positionAwareImePadding()
.verticalScroll()
.weight(1f)
) {
...
TextField(...)
}
NavigationBar { ... }
}