react-native-safe-area-context icon indicating copy to clipboard operation
react-native-safe-area-context copied to clipboard

[Hot-bug ]:Android SafeAreaProvider Top Edge Not Working on Android 15+ Devices (e.g., Samsung S21 Ultra, OnePlus 11R)

Open ajprince21 opened this issue 8 months ago • 19 comments

Description

On newer Android devices running Android 15 and above, the react-native-safe-area-context SafeAreaProvider's top inset does not correctly account for the status bar and display cutouts (notches). This results in UI content overlapping the status bar or the device's notch area, especially on devices like Samsung Galaxy S21 Ultra and OnePlus 11R.

#633

Details : info Fetching system and libraries information... System: OS: macOS 15.3.1 CPU: (8) arm64 Apple M2 Memory: 130.59 MB / 8.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 22.14.0 path: ~/.nvm/versions/node/v22.14.0/bin/node Yarn: version: 3.6.4 path: ~/.yarn/bin/yarn npm: version: 10.9.2 path: ~/.nvm/versions/node/v22.14.0/bin/npm Watchman: version: 2025.04.28.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.16.2 path: /Users/mac/.gem/ruby/3.4.0/bin/pod SDKs: iOS SDK: Platforms: - DriverKit 24.4 - iOS 18.4 - macOS 15.4 - tvOS 18.4 - visionOS 2.4 - watchOS 11.4 Android SDK: API Levels: - "33" - "34" - "35" Build Tools: - 33.0.1 - 34.0.0 - 35.0.0 - 35.0.1 System Images: - android-29 | Google APIs ARM 64 v8a - android-35 | Google APIs ARM 64 v8a - android-35 | Google Play ARM 64 v8a Android NDK: Not Found IDEs: Android Studio: 2024.2 AI-242.23726.103.2422.13016713 Xcode: version: 16.3/16E140 path: /usr/bin/xcodebuild Languages: Java: version: 17.0.14 path: /usr/bin/javac Ruby: version: 3.4.2 path: /opt/homebrew/opt/ruby/bin/ruby npmPackages: "@react-native-community/cli": installed: 18.0.0 wanted: 18.0.0 react: installed: 19.0.0 wanted: 19.0.0 react-native: installed: 0.79.2 wanted: 0.79.2 react-native-macos: Not Found npmGlobalPackages: "react-native": Not Found Android: hermesEnabled: true newArchEnabled: true iOS: hermesEnabled: true newArchEnabled: true

Image

Steps to reproduce

Install apk in Android 15 +

Snack or a link to a repository

https://stackoverflow.com/questions/79638900/android-safeareaprovider-top-edge-not-working-on-android-15-devices-e-g-sams

Safe Area Context version

5.4.1

React Native version

0.79.2

Platforms

Android

Architecture

Fabric (New Architecture)

Build type

None

Device

Real device

Device model

oneplus 11 r , samsung 21 ultra , Android Emulator - Pixel_9_Pro_XL_AP|_35:5554

Acknowledgements

Yes

ajprince21 avatar May 26 '25 12:05 ajprince21

temporary solution, you can add windowOptOutEdgeToEdgeEnforcement in styles.xml this option will be removed later in Android 16 (https://developer.android.com/about/versions/16/behavior-changes-16#edge-to-edge)

tumor800 avatar May 27 '25 06:05 tumor800

Image

mojituan avatar Jun 04 '25 09:06 mojituan

Image

thanks did the trick

const isAndroid15 = Platform.OS == 'android' && Platform.Version >= 35
return (
<SafeAreaProvider
              style={
                isAndroid15
                  ? {
                      marginBottom: initialWindowMetrics?.insets.bottom,
                    }
                  : {}
              }>

notjulian avatar Jun 25 '25 07:06 notjulian

Cannot reproduce it using both the latest image of the Android 15 emulator, or a physical device running Android 15 (a Pixel 8).

"react-native-edge-to-edge": "1.6.1"
"react-native-safe-area-context": "5.5.0"
export const App = () => (
  <SafeAreaProvider>
    <SafeAreaView style={{ backgroundColor: "red", flex: 1 }}>
      <View style={{ backgroundColor: "green", flex: 1 }} />
    </SafeAreaView>
  </SafeAreaProvider>
);

zoontek avatar Jun 25 '25 09:06 zoontek

  • 1 same issue, if you run same code on 13 android and 15
Image

litinskii avatar Jul 07 '25 07:07 litinskii

Faced the same problem on Android 15+. So far the solution for me was to add padding using insets data:

import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'
export const App = () {
const insets = useSafeAreaInsets()
return (
  <SafeAreaProvider>
    <View style={{
          paddingBottom: insets.bottom,
          paddingTop: insets.top,
      }}>
      <View/>
    </View>
  </SafeAreaProvider>
)};

When navigation is used, the padding has to be applied on the screens.

NataliaDrause avatar Jul 15 '25 05:07 NataliaDrause

Same here, using react-native-safe-area-context 5.0.0 and targetSDKVersion 35

Android 12:

Android 15:

When using targetSDKVersion 34 the problem disappears but PlayStore requires app segmentation to 35

mannoeu avatar Jul 23 '25 17:07 mannoeu

Image

doesnt work to me

mannoeu avatar Jul 23 '25 18:07 mannoeu

same problem,

<style name="OptOutEdgeToEdgeEnforcement">
        <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
    </style>

in styes.xml worked for now.

chr4ss1 avatar Jul 25 '25 14:07 chr4ss1

same problem,

<style name="OptOutEdgeToEdgeEnforcement">
        <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
    </style>

in styes.xml worked for now.

but in android 16. we can not use it any more. @chr4ss1 what can we do right now? :(

Image

ngocdinhimpl avatar Jul 29 '25 09:07 ngocdinhimpl

@ngocdinhalobridge just to clarify, as long as you target API level 35 (which I do), this fix will continue to work for Android 16 devices too. The problem will probably come around August next year when Android wants everyone to target API level 36 but by then this would be fixed for sure. If you need to target API level 36 right now, I am not sure what the solution is.

chr4ss12 avatar Jul 29 '25 09:07 chr4ss12

Can we can a timeline on when this bug will be fixed? New versions of React Native use api 36, but this bug makes those versions unusable. Using the insets doesn't seem to work well especially when switching from portrait to landscape.

Pingou avatar Sep 15 '25 07:09 Pingou

Hello everyone 👋 I finally found a solution to enable edge-to-edge support in my React Native app! 🎉

I’ve written a step-by-step guide here: https://medium.com/@ajprince0607/android-edge-to-edge-supportreact-native-app-966c8f80803c

ajprince21 avatar Sep 15 '25 18:09 ajprince21

Image

doesnt work to me  对我不起作用

我也是 请问你现在解决了吗?

hkbn-jokerliu avatar Sep 26 '25 11:09 hkbn-jokerliu

same problem,

<style name="OptOutEdgeToEdgeEnforcement">
        <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
    </style>

in styes.xml worked for now.

but in android 16. we can not use it any more. @chr4ss1 what can we do right now? :(

Image

Hi everyone, what worked for me was adding the following inside my styles.xml on Android:

<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>

Since I’m using Expo, I had to create a plugin to insert this tag. The local build worked perfectly, but for some reason the Expo build didn’t apply the tag (or maybe the solution just didn’t take effect — I’m not sure why). In the end, I generated the bundle manually and uploaded it to the Play Store.

matheus-caldeira avatar Sep 29 '25 05:09 matheus-caldeira

same problem,

<style name="OptOutEdgeToEdgeEnforcement">
        <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
    </style>

in styes.xml worked for now.

but in android 16. we can not use it any more. @chr4ss1 what can we do right now? :(

Image

Hi everyone, what worked for me was adding the following inside my styles.xml on Android:

<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>

Since I’m using Expo, I had to create a plugin to insert this tag. The local build worked perfectly, but for some reason the Expo build didn’t apply the tag (or maybe the solution just didn’t take effect — I’m not sure why). In the end, I generated the bundle manually and uploaded it to the Play Store.

windowOptOutEdgeToEdgeEnforcement only works on Android 15, not Android 16.

zoontek avatar Sep 29 '25 07:09 zoontek

Facing the same issue on the Pixel 8 device(Android version:15). react-native-safe-area-context: 5.4.0 react: 19.0.0 react-native: 0.79.2

gkasireddy202 avatar Oct 27 '25 05:10 gkasireddy202

export default function RootLayout() {
  const [themeMode, setThemeMode] = useState<ThemeMode>('light');

  const getCurrentTheme = () => {
    if (themeMode === 'highContrast') {
      return HighContrastTheme;
    }
    return DefaultTheme;
  };

  const currentTheme = getCurrentTheme();

  // Inner component to access insets
  const LayoutWithInsets = () => {
    const insets = useSafeAreaInsets();
    
    return (
      <View style={{ flex: 1, paddingBottom: Math.max(insets.bottom, 16) }}>
        <Stack>
          <Stack.Screen name="index" options={{ headerShown: false }} />
          <Stack.Screen name="camera" options={{ headerShown: false }} />
          <Stack.Screen name="Reading" options={{ headerShown: false }} />
          <Stack.Screen name="profile" options={{ headerShown: false }} />
          <Stack.Screen name="hello-world" options={{ headerShown: false }} />
          <Stack.Screen name="propertydetails" options={{ headerShown: false }} />
          <Stack.Screen name="property/[propertyId]" options={{ headerShown: false }} />
          <Stack.Screen name="modal" options={{ presentation: 'modal', headerShown: false }} />
          <Stack.Screen name="properties" options={{ headerShown: false }} />
        </Stack>
      </View>
    );
  };

  return (
    <ThemeContext.Provider value={{ themeMode, setThemeMode, theme: currentTheme }}>
      <AuthProvider>
        <ReadingSettingsProvider>
          <RoutingProvider>
            <ThemeProvider value={currentTheme}>
              <SafeAreaProvider>
                <LayoutWithInsets />
              </SafeAreaProvider>
              <StatusBar style={themeMode === 'highContrast' ? 'light' : 'dark'} />
            </ThemeProvider>
          </RoutingProvider>
        </ReadingSettingsProvider>
      </AuthProvider>
    </ThemeContext.Provider>
  );
}

Here is my _layout.tsx file. Wrapping the stack in a View with the correct insets for where you are experiencing the overlap, whether it be padding top or padding bottom, fixes the issue for me on Android.

VCSJacob avatar Nov 07 '25 00:11 VCSJacob

You could try using this. https://www.npmjs.com/package/react-native-navbar-listener

wemsaji avatar Nov 10 '25 03:11 wemsaji