实现沉浸式状态栏的关键就是使用RN官方提供的StatusBar。实现步骤可以分为以下两步:
(1)自定义StatusBar的行为;
(2)在自定义Header中使用封装好的StatusBarComp;
在开始实现前,需要明确一点,StatusBar在两个平台上的表现是有差异的。首先,在项目中,为了Header的自由度,我往往会自定义一个Header组件,而不是使用react-navigation官方提供的导航栏。当我们设置header: () => null之后,我们可以看看两个平台下默认状态栏的行为。
Android:渲染在状态栏区域y轴正下方;
iOS:渲染在状态栏区域z轴正下方;
如果想要使Android与iOS在状态栏渲染区域统一起来,我们需要用到translucent属性(这个属性是Android平台独有的),设置为true后,我们的界面也会渲染在状态栏区域z轴正下方。
接下来,我们就要考虑如何获取Android以及iOS所有机型的状态栏高度,将这部分空间预留出来。
Android:使用StatusBar.currentHeight属性获取
iOS:可以考虑使用react-native-iphone-x-helper这个库(实际上就是硬编码iPhone所有机型的高度)
有条件的同学可以自行编写双平台原生代码获取。
之后,我们就可以编写状态栏组件了:
const StatusBarComp = (props) => {
const { isDarkStyle = true, statusBarBgColor = "transparent" } = props;
return (
<View style={{ height: STATUS_BAR_HEIGHT, backgroundColor: statusBarBgColor }}>
<StatusBar
translucent={true}
backgroundColor="transparent"
barStyle={isDarkStyle ? 'dark-content' : 'light-content'}
/>
</View>
);
}
对于不需要Header组件的界面中,我们可以直接这样使用:
import React from 'react';
import { View, Text } from 'react-native';
import { StatusBarComp } from '@components';
const Intelligent = () => {
return (
<View style={{ flex: 1 }}>
<StatusBarComp />
<Text>智能</Text>
</View>
);
};
export default Intelligent;
对于需要使用公共自定义Header组件的页面,我们可以把StatusBarComp组件先导入到我们的Header组件中,再将Header组件导出使用,例如:
const Header = (props) => {
return (
<View style={[styles.container]}>
<StatusBarComp />
{/* Header主体 */}
<View style={[styles.headerContainer]}>
</View>
</View>
);
}
这样,沉浸式状态栏的功能基本也就实现了。
但是在实际使用过程中,会存在以下问题:
1. 在路由栈的初始界面(按下返回键退出APP的界面),退出APP(切到后台),再打开APP,会发现状态栏适配失效了 。
解决办法:在初始界面中重新设置一下状态栏,先封装一个函数:
const fixStatusBar = () => {
if (isAndroid) {
StatusBar.setTranslucent(true);
StatusBar.setBackgroundColor('transparent');
}
};
在对应的页面中调用上面的函数就好了。