diff --git a/android/app/src/main/kotlin/nexus/federated/nexus/MainActivity.kt b/android/app/src/main/kotlin/nexus/federated/nexus/MainActivity.kt index a243e36..ea5c3c9 100644 --- a/android/app/src/main/kotlin/nexus/federated/nexus/MainActivity.kt +++ b/android/app/src/main/kotlin/nexus/federated/nexus/MainActivity.kt @@ -1,19 +1,39 @@ package nexus.federated.nexus +import android.os.Build +import android.os.Bundle import android.view.View +import android.view.WindowInsets +import android.view.WindowInsetsAnimation import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) return + + window.decorView.setWindowInsetsAnimationCallback( + object : WindowInsetsAnimation.Callback(DISPATCH_MODE_CONTINUE_ON_SUBTREE) { + override fun onProgress( + insets: WindowInsets, + runningAnimations: List, + ) = insets + + override fun onEnd(animation: WindowInsetsAnimation) { + if ((animation.typeMask and WindowInsets.Type.ime()) != 0) reapplyInsets() + } + }, + ) + } + override fun onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) - if (!hasFocus) return + if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) reapplyInsets() + } - // Flutter swallows inset updates while it thinks a keyboard animation is - // running, and only stops when the animation ends. If the app is - // backgrounded mid-animation, it can miss the end and keep the keyboard's - // space reserved, so hand the view the real insets directly. + // Posted so it runs after Flutter has applied any insets it deferred. + private fun reapplyInsets() { val view = findViewById(FLUTTER_VIEW_ID) ?: return - val insets = view.rootWindowInsets ?: return - view.onApplyWindowInsets(insets) + view.post { view.rootWindowInsets?.let(view::onApplyWindowInsets) } } }