Skip to content

fix(android): keep BottomNavigationView pinned under the keyboard in edge-to-edge#549

Open
rayabelcode wants to merge 1 commit into
callstack:mainfrom
rayabelcode:fix/android-bottom-nav-keyboard-inset
Open

fix(android): keep BottomNavigationView pinned under the keyboard in edge-to-edge#549
rayabelcode wants to merge 1 commit into
callstack:mainfrom
rayabelcode:fix/android-bottom-nav-keyboard-inset

Conversation

@rayabelcode

Copy link
Copy Markdown
Contributor

What

Under edge-to-edge on Android, focusing a text input pushes the native tab bar up on top of the keyboard instead of letting the keyboard overlay it (iOS behavior). Fixes #357.

Why

The library delegates inset handling to Material. BottomNavigationView installs a default inset listener in its constructor that adds getSystemWindowInsetBottom() to its bottom padding, and that value includes the IME inset. With decorFitsSystemWindows=false the window is not resized, so the IME inset propagates down to the bar and Material pads it by the keyboard height every frame (material-components/material-components-android#493). windowSoftInputMode="adjustPan" does not help when react-native-keyboard-controller is present, since it forces adjustResize at runtime.

How

Give ExtendedBottomNavigationView its own OnApplyWindowInsetsListener that applies system bars + display cutout insets only, excluding Type.ime(), and returns the insets unconsumed so sibling views (the tab-screen content that hosts inputs) still receive the IME inset. Gesture-nav clearance is preserved because system-bar and cutout insets are still applied as padding.

This is a no-op outside edge-to-edge: with decorFitsSystemWindows=true the decor consumes the system insets before they reach the bar, so the computed insets are zero and padding stays at its base, and the keyboard resizes the window rather than dispatching an IME inset. Behavior only changes for the edge-to-edge case that is currently broken.

Test plan

  • Edge-to-edge app, tab-root screen with a top input: focus the input, confirm the tab bar stays pinned and the keyboard overlays it.
  • Form screen with a bottom input inside a tab: confirm keyboard avoidance still works.
  • Non-edge-to-edge build: confirm no change (bar still clears the nav bar, keyboard resizes as before).
  • Landscape / gesture-nav and 3-button nav: confirm the bar still clears the system nav bar.

…edge-to-edge

Material's BottomNavigationView adds the bottom system-window inset, which
includes the IME inset under edge-to-edge, to its own padding, so the native
tab bar rises above the keyboard. Give ExtendedBottomNavigationView its own
inset listener applying system bars and display cutout insets only, excluding
the IME type, and return the insets unconsumed so tab-screen inputs still
receive keyboard avoidance. This is a no-op outside edge-to-edge.

Fixes callstack#357
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] Tab bar sticks to keyboard instead of being hidden behind it

1 participant