Suppose I have some activity with a jetpack-compose content
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ScrollableColumn(
modifier = Modifier
.fillMaxSize()
.border(4.dp, Color.Red)
) {
val (text, setText) = remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = setText,
label = {},
modifier = Modifier
.fillMaxWidth()
)
for (i in 0..100) {
Text("Item #$i")
}
}
}
}
}
If I were to launch this activity and focus on the TextField a software keyboard would pop up.
The interface, however, would not react to it. ScrollableColumn's bottom border (.border(4.dp, Color.Red)
) would not be visible, as well as 100th item (Text("Item #$i")
).
In other words, software keyboard overlaps content.
How can I make jetpack compose respect visible area changes (due to software keyboard)?
Recomposition is when Jetpack Compose re-executes the composables that may have changed in response to state changes, and then updates the Composition to reflect any changes. A Composition can only be produced by an initial composition and updated by recomposition.
ProvideWindowInsets() {} means you can access the window inset values with LocalWindowInsets. current in any of the child compose functions inside ProvideWindowInsets() {}. With consumeWindowInsets = false, the window insect values keep passing down the view hierarchy.
Today, we're releasing version 1.2 of Jetpack Compose, Android's modern, native UI toolkit, continuing to build out our roadmap.
Jetpack Compose is designed to work with the established View-based UI approach. If you're building a new app, the best option might be to implement your entire UI with Compose.
You can use the standard android procedure, but I don't know if a Compose specific way exists.
If you set the SoftInputMode to SOFT_INPUT_ADJUST_RESIZE
, the Layout will resize on keyboard change.
class YourActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
setContent { /* Composable Content */ }
}
}
otherwise, you could use the flags in the manifest. See here for more information: Move layouts up when soft keyboard is shown?
You can use Accompanist's inset library https://google.github.io/accompanist/insets
first use ProvideWindowInsets at the root of your composable hierarchy most of the time below your app theme compose and set windowInsetsAnimationsEnabled true
ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
// content }
The use navigationBarsWithImePadding() modifier on TextField
OutlinedTextField(
// other params,
modifier = Modifier.navigationBarsWithImePadding() )
Finaly make sure to call WindowCompat.setDecorFitsSystemWindows(window, false) from your activity(inside onCreate). If you want Software keyboard on/off to animate set your activity's windowSoftInputMode adjustResize in AndroidManifests
<activity
android:name=".MyActivity"
android:windowSoftInputMode="adjustResize">
I faced the same problem.
Use OnGlobalLayoutListener
which will observe the actual IME rect size and will be triggered when the soft keyboard is fully visible.
Worked solution for me:
val bringIntoViewRequester = remember { BringIntoViewRequester() }
val scope = rememberCoroutineScope()
val view = LocalView.current
DisposableEffect(view) {
val listener = ViewTreeObserver.OnGlobalLayoutListener {
scope.launch { bringIntoViewRequester.bringIntoView() }
}
view.viewTreeObserver.addOnGlobalLayoutListener(listener)
onDispose { view.viewTreeObserver.removeOnGlobalLayoutListener(listener) }
}
TextField(
modifier = Modifier.bringIntoViewRequester(bringIntoViewRequester),
...
)
Origin here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With