功能
在设备安全区域内容展示页面内容:


原理
本质是个View组件,但会自动添加padding。
SafeAreaView不是无脑的添加padding,而是在适当的时候添加padding:
- 上边缘触摸了设备顶部,即
坐标Y === 0;
- 左边缘触摸了设备左部,即
坐标X === 0;
- 下边缘超过设备底部,即
坐标Y + View高度 >= 设备高度;
- 右边缘超过设备右部,即
坐标X + View宽度 >= 设备宽度;
当SafeAreaView四边处于以上4中情况时,则会给边缘添加合适的padding。
具体实现可以参考react-native-safe-area-view库_getSafeAreaStyle方法的实现。
// 检查`SafeAreaView`边缘是否触碰到设备边缘
_updateMeasurements = () => {
if (!this._isMounted) return;
if (!this._view.current) return;
const { width: WIDTH, height: HEIGHT } = getResolvedDimensions();
// calling getNode on the ref is no longer necessary in the future
const view = this._view.current.measureInWindow
? this._view.current
: this._view.current.getNode();
view.measureInWindow((realX, realY, winWidth, winHeight) => {
if (!this._view.current) {
return;
}
if (realY >= HEIGHT) {
realY = realY % HEIGHT;
} else if (realY < 0) {
realY = (realY % HEIGHT) + HEIGHT;
}
if (realX >= WIDTH) {
realX = realX % WIDTH;
} else if (realX < 0) {
realX = (realX % WIDTH) + WIDTH;
}
let nextState = {
touchesTop: realY === 0,
touchesBottom: realY + winHeight >= HEIGHT,
touchesLeft: realX === 0,
touchesRight: realX + winWidth >= WIDTH,
viewWidth: winWidth,
viewHeight: winHeight,
};
if (!shallowEquals(nextState, this.state)) {
this.setState(nextState);
}
});
};
使用
包裹整个页面组件
如果只是简单的把页面内容展示安全区域内,可以用SafeAreaView+flex: 1包裹页面组件即可。正如RN官方的[DEMO]:(https://reactnative.dev/docs/safeareaview#example):
import React from 'react';
import {StyleSheet, Text, SafeAreaView} from 'react-native';
const App = () => {
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Page content</Text>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
text: {
fontSize: 25,
fontWeight: '500',
},
});
export default App;
头部组件
为了实现更好的沉浸式头部组件(Header, Tab等)可以在这些组件内部使用SafeAreaView。
底部组件
跟头部组件类似,还有些页面底部的组件中可以直接使用SafeAreaView。
Issues/Concern
- 不能给
SafeAreaView显示的指定padding相关属性。
- 在
ScrollView内部使用SafeAreaView时会发生页面抖动。解决方案:contentInsetAdjustmentBehavior="automatic"
参考
- ReactNative
SafeAreaView
- iOS Safe Area
- SafeAreaView doesn't respect padding property in style #22211
- Having a
SafeAreaView inside ScrollView breaks scrolling #19658
- react-native-safe-area-context
SafeAreaView组件功能
在设备安全区域内容展示页面内容:


原理
本质是个
View组件,但会自动添加padding。SafeAreaView不是无脑的添加padding,而是在适当的时候添加padding:坐标Y === 0;坐标X === 0;坐标Y + View高度 >= 设备高度;坐标X + View宽度 >= 设备宽度;当
SafeAreaView四边处于以上4中情况时,则会给边缘添加合适的padding。具体实现可以参考
react-native-safe-area-view库_getSafeAreaStyle方法的实现。使用
包裹整个页面组件
如果只是简单的把页面内容展示安全区域内,可以用
SafeAreaView+flex: 1包裹页面组件即可。正如RN官方的[DEMO]:(https://reactnative.dev/docs/safeareaview#example):头部组件
为了实现更好的沉浸式头部组件(Header, Tab等)可以在这些组件内部使用
SafeAreaView。底部组件
跟头部组件类似,还有些页面底部的组件中可以直接使用
SafeAreaView。Issues/Concern
SafeAreaView显示的指定padding相关属性。ScrollView内部使用SafeAreaView时会发生页面抖动。解决方案:contentInsetAdjustmentBehavior="automatic"参考
SafeAreaViewSafeAreaViewinsideScrollViewbreaks scrolling #19658