Skip to content

[Android] BottomNavigationView pushed above keyboard in edge-to-edge modeΒ #3647

@FranDepascuali

Description

@FranDepascuali

Description

When using native bottom tabs on Android with edgeToEdgeEnabled: true, the tab bar is pushed above the keyboard when typing in a TextInput. This happens because Material's BottomNavigationView automatically consumes IME window insets in edge-to-edge mode.

Setting softwareKeyboardLayoutMode: 'pan' or KeyboardController.setInputMode(SOFT_INPUT_ADJUST_NOTHING) does not fix this, because the BottomNavigationView handles insets at the view level, independent of the activity's soft input mode.

Steps to reproduce

  1. Enable edgeToEdgeEnabled: true in Expo app config
  2. Use NativeTabs (which renders TabsHost with BottomNavigationView)
  3. Navigate to a screen with a TextInput inside the tabs
  4. Focus the input β€” keyboard appears, tab bar stays behind it (correct)
  5. Start typing β€” the tab bar jumps above the keyboard (incorrect)

Expected behavior

The tab bar should remain behind the keyboard, not be pushed above it.

Root cause

In TabsHost.kt, the BottomNavigationView is created without stripping IME insets:

https://github.com/software-mansion/react-native-screens/blob/main/android/src/main/java/com/swmansion/rnscreens/gamma/tabs/TabsHost.kt

Material's BottomNavigationView automatically applies IME insets as padding in edge-to-edge mode. This is documented in material-components-android#493.

Fix

Adding a ViewCompat.setOnApplyWindowInsetsListener that strips IME insets from the BottomNavigationView resolves the issue:

private val bottomNavigationView: BottomNavigationView =
    BottomNavigationView(wrappedContext).apply {
        layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
        ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets ->
            val insetsWithoutIme = WindowInsetsCompat.Builder(insets)
                .setInsets(WindowInsetsCompat.Type.ime(), Insets.NONE)
                .build()
            ViewCompat.onApplyWindowInsets(view, insetsWithoutIme)
        }
    }

Environment

  • react-native-screens: 4.16.0 (also confirmed not fixed on main / 4.23.0)
  • expo-router/unstable-native-tabs
  • Android with edgeToEdgeEnabled: true
  • react-native-keyboard-controller as KeyboardProvider

Screens version

4.16.0

React Native version

0.81.5

Platforms

Android

Metadata

Metadata

Assignees

No one assigned

    Labels

    Missing infoThe user didn't precise the problem enoughMissing reproThis issue need minimum repro scenarioPlatform: AndroidThis issue is specific to Android

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions