improve WindowInsetsCallback to work when keyboard changes size (#4947)

re: https://chaos.social/@jannik/114059313885014801

Not sure why I didn't use `onPrepare` previously 🤔 . Makes more sense
this way.

The difference between `onStart` and `onPrepare` is that `onPrepare` is
called before the `OnApplyWindowInsetsListener` and the other after. So
with `onPrepare` it is easy to detect that an animation is starting. The
keyboard only seems to animate initially, not when it changes size
later, but the previous code always expected an animation.
This commit is contained in:
Konrad Pozniak 2025-02-27 09:58:04 +01:00 committed by GitHub
commit 1e1695de6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -26,7 +26,6 @@ import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsAnimationCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsCompat.Type.ime
import androidx.core.view.WindowInsetsCompat.Type.systemBars
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
@ -152,12 +151,11 @@ private class WindowInsetsCallback(
) : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP),
OnApplyWindowInsetsListener {
var imeVisible = false
var animationRunning = false
var deferredInsets: WindowInsetsCompat? = null
override fun onStart(animation: WindowInsetsAnimationCompat, bounds: WindowInsetsAnimationCompat.BoundsCompat): WindowInsetsAnimationCompat.BoundsCompat {
imeVisible = true
return super.onStart(animation, bounds)
override fun onPrepare(animation: WindowInsetsAnimationCompat) {
animationRunning = true
}
override fun onProgress(
@ -172,8 +170,7 @@ private class WindowInsetsCallback(
view: View,
insets: WindowInsetsCompat,
): WindowInsetsCompat {
val ime = insets.getInsets(ime()).bottom
if (!imeVisible && ime == 0) {
if (!animationRunning) {
listener(insets)
deferredInsets = null
} else {
@ -183,10 +180,10 @@ private class WindowInsetsCallback(
}
override fun onEnd(animation: WindowInsetsAnimationCompat) {
imeVisible = deferredInsets?.isVisible(ime()) == true
deferredInsets?.let { insets ->
listener(insets)
deferredInsets = null
}
animationRunning = false
}
}