最近在开发导航组件过程中有涉及到StatusBar控制状态栏样式的问题,以下对遇到的问题进行记录总结。

react-native为移动端开发控制状态栏提供了StatusBar组件,同时StatusBar也暴露出一个静态API,但是如果通过静态API或在同一组件上渲染相同属性,则后渲染的属性会覆盖前面渲染的属性,我所修改的组件就是出现了这个问题,在原组件中是通过StatusBar.setBarStyle来对状态栏字体样式进行设置,当通过点击进入新页面导航样式改变时,状态栏样式也会随之改变,但是当从新页面回退到原页面时,原页面不会重新渲染,原页面的状态栏字体样式已经被新页面的样式改变所覆盖,这样就会产生样式不协调的问题。

我解决此问题的过程:

我想到的第一种方法就是在每个组件中都引入StatusBar组件,这样每个组件都有属于自己的StatusBar组件,这样当切换页面时设置状态栏样式的时候就不会产生覆盖原页面的状态栏式。

StatusBar

常量

currentHeight(仅Android):获取状态栏高度

StatusBar.currentHeight

通用属性

1.animated(bool类型)

(1)设置当前状态栏发生变化时是否需要加入动画。

(2)动画支持backgroundColor、barStyle和hidden属性的变化。

<StatusBar animated = {true}> </StatusBar>

2.barStyle(类型:enum('default', 'light-content', 'dark-content'))

设置状态栏字体样式

<StatusBar barStyle = {'light-content'}> </StatusBar>

3.hidden(bool类型)

设置状态栏显示与隐藏

<StatusBar hidden = {true}> </StatusBar>

Android属性

1.backgroundColor(color类型)

设置状态栏背景颜色

<StatusBar backgroundColor = {'#000000'}> </StatusBar>

2.translucent(bool类型)

设置状态栏是否为透明,当属性值为true时,应用组件会延申到状态栏之下绘制(沉浸式)。

<StatusBar translucent = {true}> </StatusBar>

ios属性

1.networkActivityIndicatorVisible(bool类型)

设置是否显示网络活动提示符

<StatusBar networkActivityIndicactorVisible = {true}> </StatusBar>

2.showHideTransition(类型:enum('fade', 'slide'))

设置通过hidden属性来显示或隐藏状态栏时所使用的动画效果,默认值:fade

<StatusBar showHideTransition = {'slide'}> </StatusBar>

通用方法

1.setHidden()

控制状态栏显示与隐藏,可传递动画方式。

StatusBar.setHidden(hidden: boolean, [animation]: StatusBarAnimation);

2.setBarStyle()

设置状态栏字体样式,可设置是否启用过渡动画。

StatusBar.setBarStyle(style: StatusBarStyle, [animated]: boolean);

Android方法

1.setBackgroundColor()

设置状态栏背景色,可设置是否启用过渡动画。

StatusBar.setBackgroundColor(color: string, [animated]: boolean);

2.setTranslucent()

设置状态栏是否透明。

StatusBar.setTranslucent(translucent: boolean);

ios方法

setNetworkActivityIndicatorVisible()

设置是否显示网络状态图标。

StatusBar.setNetworkActivityIndicatorVisible(visible: boolean);

当我使用此方法对组件进行修改后,组件又产生了新问题:状态栏的样式切换会明显慢于页面切换。虽然实现了状态栏切换随页面样式而改变,但是显示效果明显很差。

为了解决这个问题,我想到了新的方法:监听页面的聚焦行为,在页面被聚焦前设置页面的状态栏字体样式。

监听页面的三个方法:

(1)useFocusEffect

当页面聚焦时想要产生某些副作用,其中包括添加事件监听器,获取数据,更新文档标题等。虽然这可以实现使用和事件,但它不是很符合人体工程学,由此引出了一个挂钩:useFocus-Effect。

useFocusEffect与useEffect的区别在于,useEffect需要手动添加监听addListener,useIs-Focused(值改变的时候)会导致组件重新渲染,而useFocusEffect只要传递的依赖项通过React.useCallBack发生变化,该effect就会重新运行,如果不将效果通过React.useFocusEffect进行包装,则当屏幕聚焦时effect将运行每一个渲染。

import { useFocusEffect } from '@react-navigation/native';function Profile({ userId }) {const [user, setUser] = React.useState(null);useFocusEffect(React.useCallback(() => {const unsubscribe = API.subscribe(userId, user => setUser(user));return () => unsubscribe();}, [userId]));return <ProfileContent user={user} />;
}

useFocusEffect与为焦点添加监听事件的区别:

为焦点添加监听事件,当订阅事件之前屏幕已经聚焦,则不会触发监听事件,并且焦点事件没有提供当屏幕无焦点时的事件清理方法,通常需要在componentDidMount和componentWillUn-mount方法中进行处理。

useFocusEffect运行在焦点上运行一个效果,并在屏幕无焦点时进行清理,同时处理卸载时的清理。当依赖项更改时,将重新运行效果,不需要担心监听器中的陈旧值。

可以使用useFocusEffect为效果创建一个组件,并与类组件共同使用:

function FetchUserData({ userId, onUpdate }) {useFocusEffect(React.useCallback(() => {const unsubscribe = API.subscribe(userId, onUpdate);return () => unsubscribe();}, [userId, onUpdate]));return null;
}// ...class Profile extends React.Component {_handleUpdate = user => {// Do something with user object};render() {return (<><FetchUserDatauserId={this.props.userId}onUpdate={this._handleUpdate}/>{/* rest of your code */}</>);}
}

(2)Navigation.addListener

在app每一个screen组件中都自动具有了navigation属性:

this.props.navigation(属性):

navigate - 跳转到其他screen

goBack - 关闭当前screen回退栈

addListener - 焦点事件

isFocused - 当前screen获取了焦点返回true,否则返回false

state - 当前路由状态

setParams - 设置路由参数

getParam - 获取路由参数

dispatch - 向路由发送action

注意:navigation属性并不是每个页面都会具有,只有screen组件才会自动接收属性。

通过navigation.addListener进行焦点监听,向订阅过的screen发送事件:

willBlur:将要失去焦点

willFocus:将要获取焦点

didBlur:已经失去焦点

didFocus:已经获取焦点

UNSAFE_componentWillMount() {this.controlStatusBar = this.props.navigation.addListener("willFocus",()=>{ StatusBar.setBarStyle(this.isDarkStyle ? 'light-content' : 'dark-content');})}componentWillUnMount(){this.controlStatusBar.remove();}

(3)NavigationEvents

NavigationEvents是React-navigation导出的一个组件,具有五个属性,任何组件上都可以放置此组件。

onWillFocus:将要获取焦点

onWillBlur:将要失去焦点

onDidFocus:已经获取焦点

onDidBlur:已经失去焦点

import React from 'react';
import { View } from 'react-native';
import { NavigationEvents } from 'react-navigation';const MyScreen = () => (<View><NavigationEventsonWillFocus={payload => console.log('will focus', payload)}onDidFocus={payload => console.log('did focus', payload)}onWillBlur={payload => console.log('will blur', payload)}onDidBlur={payload => console.log('did blur', payload)}/>{/*Your view code*/}</View>);export default MyScreen;

路由事件会依次向下传导,父组件和子组件事件处理函数会依次被触发,parent willFocus > child willFocus > parent didFocus > child didFocus。

StatusBar状态栏设置及设备适配相关推荐

  1. 关于LaunchScreen.storyboard启动设置(包含不同设备适配)

    消除警告 1.warning: Launch images are deprecated in iOS 13.0. Use a launch storyboard or XIB instead. 2. ...

  2. 沉浸式状态栏实现,完美适配Android刘海屏,终极兼容

    第一篇博客献给曾经帮助我N次的CSDN,在此感谢那些帮助我头发越来越少的***. 刘海屏出来有一段时间了,为了适配刘海屏找了不少方案,感觉都比较费劲. 因为我们项目需求,状态栏是渐变色,所以我采用了全 ...

  3. 【已解决】联想小新14无线图标消失 | 网络适配器有感叹号 | Windows仍在设置此设备的类配置(代码56)的解决方法

    我的电脑型号是联想小新Air-14IIL 2020,起因是系统让我更新驱动(具体什么驱动忘记了),更新后发现网络里只剩飞行模式,没有WLAN,也没有移动热点了,查看设备管理器发现网络适配器下所有驱动都 ...

  4. Android StatusBar相关设置

    Android StatusBar设置 自 4.4 版本(API 19)以后,Android 系统开始支持状态栏的定制,并被纳入 Android 设计规范当中. statusBar的颜色设置 通过th ...

  5. android 状态栏设置工具栏,Android状态栏工具

    参考了一些文章做了一些修改,变成了自己的工具类.其中有很多地方欠考虑,有待改进,欢迎路过的大佬给点建议. 经过前两篇的介绍我们对如何修改状态栏的效果有了大致的了解,本篇介绍一种使用更加简单的方式 设置 ...

  6. Android 12 adb 串口指令设置耳机音量适配

    1.突然接到测试部一个需求 耳机录音在Android 12 直接运行崩溃,后面抓取日志一看是执行shell指令出现问题,看着日志我也没有特别清晰的思路 2.跳坑 于是我拿了之前另外一台Android ...

  7. 《Qt》part 10 Qt5.5 状态栏设置

    <Qt>part 10 Qt5.5 状态栏设置 1.普通的状态栏(statusBar) 在程序的普通模式下,状态栏包括连个状态指示器:当前的操作指示,也用于显示状态提示和其他的一些临时消息 ...

  8. oppo禁用android系统通知栏,状态栏设置OPPO版

    <状态栏设置 OPPO版>是一款为OPPO手机精心打造的手机美化状态栏的软件.这款软件让手机中平白无奇普普通通的状态栏可以花里胡哨,也更加有了和自己的性格相互匹配的个性!赶快来动手制作属于 ...

  9. 2018-8-10-三种方式设置特定设备UWP-XAML-view

    title author date CreateTime categories 三种方式设置特定设备UWP XAML view lindexi 2018-08-10 19:16:52 +0800 20 ...

最新文章

  1. 1. 验证集 -- 批量测试和可视化 2. 测试集 -- 批量测试和可视化
  2. php windows应用开发,开发老手谈Windows平台的PHP应用开发
  3. SVN使用之分支、合并
  4. MDEV Primer
  5. 成功解决AttributeError: module ‘dask.array.numpy_compat‘ has no attribute ‘take_along_axis‘
  6. 笔记-项目整体管理-变更管理-实施整体变更控制
  7. 《计算机网络》第四章:介质访问控制(The Medium Access Control Sublayer)
  8. wifi频率和zigbee干扰_浅谈ZigBee和Wi—Fi的共存和干扰
  9. C及C++中的一些基础知识点(持续更新)
  10. 非广告--推荐Dynatrace:树立数字化性能管理DPM标杆
  11. shell for循环两个变量并列_从Go汇编角度解释for循环的两个疑点
  12. 各纬度气候分布图_气候分布图有纬度
  13. 微信api中转站(用python搭建flask服务器)
  14. 串行加法器 并行加法器 超前进位加法器
  15. 2021-2027全球与中国USB C型集线器市场现状及未来发展趋势
  16. What Makes a Video a Video :Analyzing Temporal Information in Video Understanding Models and Dataset
  17. 三星S6D1121主控彩屏(240*320*18bit,262K)驱动程序
  18. FPGA中ROM IP与RAM IP核配置与调用
  19. Observability: 如何为 APM 定制 transactions 及 spans
  20. IDEA 设置默认的JDK

热门文章

  1. php采集节目单,电视节目预告
  2. Ubuntu下装个音乐播放器
  3. python课程多少钱-python培训学费多少钱 学python课程价格是多少
  4. 程序员吐槽_程序员神吐槽用户
  5. 花式拖稿大法,设计师直呼666
  6. HIT_SC:实验回顾 - Lab3
  7. SC9832 Android7.0 基准仓库建立
  8. 2020高考报计算机专业指南,2020高考报考指南电子版
  9. 组合导航学习笔记--开环闭环介绍
  10. js中几种追加元素的方法