IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> StatusBar状态栏设置及设备适配 -> 正文阅读

[移动开发]StatusBar状态栏设置及设备适配

????????最近在开发导航组件过程中有涉及到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 (
      <>
        <FetchUserData
          userId={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>
     <NavigationEvents
       onWillFocus={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。

???????

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-03 12:02:02  更:2021-09-03 12:04:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 12:45:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码