With the release of Android 15 (API 35) and React Native 0.76, edge-to-edge layouts have become the default for modern Android apps. This change emphasizes the importance of handling safe area insets properly. If you’ve relied on React Native’s SafeAreaView
, you’ve likely discovered that it doesn’t work on Android, as it was only designed with iOS’s notch in mind. Thankfully, the react-native-safe-area-context
library offers a cross-platform solution that supports both Android and iOS.
In this article, we’ll walk you through the steps to replace SafeAreaView
with View
and utilize react-native-safe-area-context
to ensure your layouts adapt to safe area insets correctly on Android.
Steps to Adapting Layout for Edge-to-Edge in React Native Android 15 (API 35)
1. Install the react-native-safe-area-context
Library
If you haven’t already, add the library to your project using either npm or Yarn:
npm install react-native-safe-area-context
or
yarn add react-native-safe-area-context
2. Wrap your App with SafeAreaProvider
Add the SafeAreaProvider
component to the root of your app and provide initialWindowMetrics
to improve performance and avoid layout jumps on startup.
You can retrieve initialWindowMetrics
from react-native-safe-area-context
.
import React from 'react';
import { SafeAreaProvider, initialWindowMetrics } from 'react-native-safe-area-context';
import MyApp from './MyApp';
const App = () => (
<SafeAreaProvider initialMetrics={initialWindowMetrics}>
<MyApp />
</SafeAreaProvider>
);
export default App;
3. Use Safe Area Insets Padding on Outer Views to Push Content out of Screen Edge
You can get child content to push into the safe area away from the screen edges by using padding on the outermost view. You should use useSafeAreaInsets
for functional components, and withSafeAreaInsets
for class components.
Examples
Functional Component
Here’s how to use the useSafeAreaInsets
hook in a functional component:
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const MyFunctionalComponent: React.FC = () => {
const insets = useSafeAreaInsets();
return (
<View
style={{
...styles.container,
paddingTop: insets.top,
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
}}
>
<Text>Hello, world!</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
});
export default MyFunctionalComponent;
Class Component
Here’s how to use the withSafeAreaInsets
higher-order component (HOC) in a class component:
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { withSafeAreaInsets, SafeAreaInsetsContext } from 'react-native-safe-area-context';
interface Props {
insets: SafeAreaInsetsContext;
}
class MyClassComponent extends React.Component<Props> {
render() {
const { insets } = this.props;
return (
<View
style={{
...styles.container,
paddingTop: insets?.top,
paddingBottom: insets?.bottom,
paddingLeft: insets?.left,
paddingRight: insets?.right,
}}
>
<Text>Hello, world!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
});
export default withSafeAreaInsets(MyClassComponent);
That’s it! You can also decide which sides (top, bottom, left and right) you want to apply padding to based on the design of your screen. If you’re not sure, applying it to all sides and seeing how the screen looks is best.
Remarks
- While
react-native-safe-area-context
exports aSafeAreaView
component, our experience indicates that it can also lead to screen jumping issues, especially on iOS. Therefore, it’s still better to use theuseSafeAreaInsets
hook for functional components or thewithSafeAreaInsets
HOC for class components. - Passing
initialWindowMetrics
toSafeAreaProvider
ensures accurate safe area insets on app startup, preventing layout jumps caused by delayed inset calculations. - For testing, you’ll want to use an Android emulator or phone that supports edge-to-edge and is running at least Android 15 (API 35), such as the Google Pixel 8.
- If you were previously using
SafeAreaView
fromreact-native
for iOS, you should remove all instances ofSafeAreaView
from your code. You can cross-reference our iOS guide here.
Leave a Reply