Skip to content

Commit 74625ae

Browse files
authored
Keyboard padding detection heuristic to distringuish when to include bottom inset. (#6288)
Use a screen height ratio to determine if the keyboard is onscreen or not. This is used because Android does not provide a deterministic API to detect this. We remove the padding when the keyboard is closed and the inset is due to the hidden navigation bar, otherwise, we apply the full keyboard inset.
1 parent 617b122 commit 74625ae

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

shell/platform/android/io/flutter/view/FlutterView.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,29 @@ else if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
575575
return ZeroSides.NONE;
576576
}
577577

578+
// TODO(garyq): Use clean ways to detect keyboard instead of heuristics if possible
579+
// TODO(garyq): The keyboard detection may interact strangely with
580+
// https://github.com/flutter/flutter/issues/22061
581+
582+
// Uses inset heights and screen heights as a heuristic to determine if the insets should
583+
// be padded. When the on-screen keyboard is detected, we want to include the full inset
584+
// but when the inset is just the hidden nav bar, we want to provide a zero inset so the space
585+
// can be used.
586+
int calculateBottomKeyboardInset(WindowInsets insets) {
587+
int screenHeight = getRootView().getHeight();
588+
// Magic number due to this being a heuristic. This should be replaced, but we have not
589+
// found a clean way to do it yet (Sept. 2018)
590+
final double keyboardHeightRatioHeuristic = 0.18;
591+
if (insets.getSystemWindowInsetBottom() < screenHeight * keyboardHeightRatioHeuristic) {
592+
// Is not a keyboard, so return zero as inset.
593+
return 0;
594+
}
595+
else {
596+
// Is a keyboard, so return the full inset.
597+
return insets.getSystemWindowInsetBottom();
598+
}
599+
}
600+
578601
// This callback is not present in API < 20, which means lower API devices will see
579602
// the wider than expected padding when the status and navigation bars are hidden.
580603
@Override
@@ -602,8 +625,10 @@ public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
602625
// Bottom system inset (keyboard) should adjust scrollable bottom edge (inset).
603626
mMetrics.physicalViewInsetTop = 0;
604627
mMetrics.physicalViewInsetRight = 0;
605-
// TODO(garyq): Detect and distinguish between bottom nav padding and keyboard padding.
606-
mMetrics.physicalViewInsetBottom = insets.getSystemWindowInsetBottom();
628+
// We perform hidden navbar and keyboard handling if the navbar is set to hidden. Otherwise,
629+
// the navbar padding should always be provided.
630+
mMetrics.physicalViewInsetBottom =
631+
navigationBarHidden ? calculateBottomKeyboardInset(insets) : insets.getSystemWindowInsetBottom();
607632
mMetrics.physicalViewInsetLeft = 0;
608633
updateViewportMetrics();
609634
return super.onApplyWindowInsets(insets);

0 commit comments

Comments
 (0)