rntpc_react-native-safe-area-context:基于 react-native-safe-area-context 的 OpenHarmony 适配版,用于获取设备安全区域(刘海屏、状态栏、底部导航栏)的 insets 信息

基于 react-native-safe-area-context 的 OpenHarmony 适配版,用于获取设备安全区域(刘海屏、状态栏、底部导航栏)的 insets 信息

分支5Tags4
当前项目代码仓暂无内容

文档模板:v0.4.2

react-native-safe-area-context

本项目基于 react-native-safe-area-context 开发。

该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-safe-area-context 版本所属关系如下:

三方库名称 三方库版本(npm地址) 发布信息 支持RN版本 Autolink 编译API版本 社区基线版本 源码地址
@react-native-ohos/react-native-safe-area-context ~ 5.1.1 Gitcode Releases 0.77.* API12+ 5.1.0 br_rnoh0.77

对于未发布到npm的旧版本,请参考安装指南安装tgz包。

简介

react-native-safe-area-context 是一个提供安全区域上下文的 React Native 库。
它允许开发者获取设备安全区域的 insets(插入值)和 frame(帧信息),以便正确处理刘海屏、圆角、状态栏等区域的内容布局。
该库提供了 SafeAreaProvider、SafeAreaView 组件以及多个 Hooks,使应用能够自适应不同设备的屏幕安全区域。

下载安装

进入到工程目录并输入以下命令:

npm

npm install @react-native-ohos/react-native-safe-area-context

yarn

yarn add @react-native-ohos/react-native-safe-area-context
是否支持autolink RN框架版本
~ 5.1.1 No 0.77

使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md

如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。

ManualLink: 此步骤为手动配置原生依赖项的指导。

首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony

1. Overrides RN SDK

为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 oh-package.json5 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。

关于该字段的作用请阅读官方说明

{
  "overrides": {
    "@rnoh/react-native-openharmony": "^0.77.33" // ohpm 在线版本
    // "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // 指向本地 har 包的路径
    // "@rnoh/react-native-openharmony" : "./react_native_openharmony" // 指向源码路径
  }
}

2. 引入原生端代码

目前有两种方法:

  • 通过 har 包引入;
  • 直接链接源码。

方法一:通过 har 包引入(推荐)

har 包位于三方库安装路径的 `harmony` 文件夹下。

打开 entry/oh-package.json5,添加以下依赖

"dependencies": {
    "@react-native-ohos/react-native-safe-area-context": "file:../../node_modules/@react-native-ohos/react-native-safe-area-context/harmony/safe_area.har"
  }

点击右上角的 sync 按钮

或者在命令行终端执行:

cd entry
ohpm install

方法二:直接链接源码

如需使用直接链接源码,请参考[直接链接源码说明](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/link-source-code.md)

3. 配置 CMakeLists 和引入 SafeAreaViewPackage

打开 entry/src/main/cpp/CMakeLists.txt,添加:

project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
set(LOG_VERBOSITY_LEVEL 1)
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
add_compile_definitions(WITH_HITRACE_SYSTRACE)

add_subdirectory("${RNOH_CPP_DIR}" ./rn)

# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-safe-area-context/src/main/cpp" ./safe-area)
# RNOH_END: manual_package_linking_1

file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")

add_library(rnoh_app SHARED
    ${GENERATED_CPP_FILES}
    "./PackageProvider.cpp"
    "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)

# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_safe_area)
# RNOH_END: manual_package_linking_2

打开 entry/src/main/cpp/PackageProvider.cpp,添加:

#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"
#include "SamplePackage.h"
+ #include "SafeAreaViewPackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
      std::make_shared<RNOHGeneratedPackage>(ctx),
      std::make_shared<SamplePackage>(ctx),
+     std::make_shared<SafeAreaViewPackage>(ctx)
    };
}

4. 在 ArkTs 侧引入 SafeAreaViewPackage

打开 entry/src/main/ets/RNPackagesFactory.ts,添加:

...
+ import {SafeAreaViewPackage} from '@react-native-ohos/react-native-safe-area-context/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [
    new SamplePackage(ctx),
+   new SafeAreaViewPackage(ctx)
  ];
}

运行

点击右上角的 sync 按钮

或者在命令行终端执行:

cd entry
ohpm install

然后编译、运行即可。

约束与限制

兼容性

要使用此库,需要使用正确的 React-Native 和 RNOH 版本。另外,还需要使用配套的 DevEco Studio 和 手机 ROM。

在以下版本验证通过:

  1. RNOH: 0.77.18; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;

编译运行API要求

当前三方库所有版本均已实现版本隔离,支持在 `API12+` 工程编译,及 `API12+` ROM运行。

使用示例

下面的代码展示了这个库的基本使用场景:

使用时 import 的库名不变。

import React from "react";
import { Text, View } from "react-native";
import {
  SafeAreaProvider,
  SafeAreaView,
  initialWindowMetrics,
} from "react-native-safe-area-context";

const App = () => {
  return (
    <SafeAreaProvider initialMetrics={initialWindowMetrics}>
      <SafeAreaView style={{ flex: 1, backgroundColor: "red" }}>
        <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
          <Text>hello</Text>
        </View>
      </SafeAreaView>
    </SafeAreaProvider>
  );
};

export default App;

使用说明

SafeAreaProvider

您应该在应用的根组件中添加 SafeAreaProvider。在使用 react-native-screens 时,您可能还需要在其他地方添加它,例如模态框和路由的根部。

请注意,Provider 不应放在使用 Animated 动画的 View 内或 ScrollView 内,因为这可能导致非常频繁的更新。

SafeAreaView

SafeAreaView 是一个常规的 View 组件,并将安全区域插入(insets)应用为 padding 或 margin。

Hooks

import { useSafeAreaInsets, useSafeAreaFrame } from "react-native-safe-area-context";

const App = () => {
  const insets = useSafeAreaInsets();
  const frame = useSafeAreaFrame();

  return (
    <View style={{ paddingTop: insets.top, flex: 1 }}>
      <Text>Frame: {frame.width} x {frame.height}</Text>
    </View>
  );
};

接口说明

"Platform"列表示该属性在原三方库上支持的平台。

"HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

组件

SafeAreaProvider

名称 参数类型 默认值 必填 平台 HarmonyOS平台支持 描述
Props object {flex:1} All Yes 接受所有 View 属性。
initialMetrics Metrics | null - All Yes 可用于提供 frame 和 insets 的初始值,允许立即渲染(优化首屏)。
initialSafeAreaInsetsdeprecated EdgeInsets | null - All Yes 已废弃。旧版用于提供初始 inset,推荐使用 initialMetrics

SafeAreaView

名称 参数类型 默认值 必填 平台 HarmonyOS平台支持 描述
Props object {flex:1} All Yes 接受所有 View 属性。
edges Edge[] | EdgeRecord all All Yes 设置要应用安全区域 inset 的边。数组形式:['top', 'right', 'bottom', 'left'];对象形式:{ top: 'off' | 'additive' | 'maximum', ... }EdgeMode 取值:off=不应用、additive=累加 inset + padding(默认)、maximum=取较大值 max(inset, padding)。未指定的边默认 off
mode 'padding' | 'margin' padding All Yes 可选 padding(默认)或 margin,决定 inset 作用于 padding 还是 margin。

Hooks

名称 类型 参数类型 返回值 必填 平台 HarmonyOS平台支持 描述
useSafeAreaInsets function / EdgeInsets All Yes 返回最近 Provider 的安全区域 inset。
useSafeAreaFrame function / Rect All Yes 返回最近 Provider 的 frame,可作为 Dimensions 模块的替代。
useSafeAreadeprecated function / EdgeInsets All Yes 已废弃,useSafeAreaInsets 的别名。

高阶组件(HOC)

名称 类型 参数类型 返回值 必填 平台 HarmonyOS平台支持 描述
withSafeAreaInsets function WrappedComponent Component All Yes 高阶组件,将安全区域 inset 作为 insets 属性提供给被包裹组件。

Context

名称 类型 参数类型 返回值 必填 平台 HarmonyOS平台支持 描述
SafeAreaInsetsContext object / EdgeInsets | null All Yes 提供 inset 值的 React Context。
SafeAreaFrameContext object / Rect | null All Yes 提供 frame 值的 React Context。
SafeAreaContextdeprecated object / EdgeInsets | null All Yes 已废弃,SafeAreaInsetsContext 的别名。
SafeAreaConsumerdeprecated object / EdgeInsets | null All Yes 已废弃,SafeAreaInsetsContext.Consumer

常量

名称 类型 参数类型 返回值 必填 平台 HarmonyOS平台支持 描述
initialWindowMetrics object / Metrics | null All Yes 初始渲染时窗口的 inset 和 frame,可与 SafeAreaProviderinitialMetrics 配合使用。
initialWindowSafeAreaInsetsdeprecated object / EdgeInsets | null All Yes 已废弃,旧版初始 inset 常量。

类型定义

类型 取值 参数类型 返回值 必填 平台 HarmonyOS平台支持 说明
Edge 'top' | 'right' | 'bottom' | 'left' / / All Yes 安全区域的四条边。
EdgeMode 'off' | 'additive' | 'maximum' / / All Yes 单边 inset 的应用模式。
EdgeRecord Partial<Record<Edge, EdgeMode>> / / All Yes 边到模式的映射,用于 SafeAreaView.edges 的对象形式。
Edges readonly Edge[] | Readonly<EdgeRecord> / / All Yes SafeAreaView.edges 的类型,数组或对象形式。
EdgeInsets { top: number; right: number; bottom: number; left: number } / / All Yes 安全区域 inset 值。
Rect { x: number; y: number; width: number; height: number } / / All Yes 窗口 frame 矩形。
Metrics { insets: EdgeInsets; frame: Rect } / / All Yes inset 与 frame 的组合,initialWindowMetrics 的类型。

遗留问题

当前版本无已知遗留问题,如发现问题请提交 Issue

其他

目录结构

/rntpc_react-native-safe-area-context  # 项目根目录
├── harmony                                    # 鸿蒙适配代码
│   ├── safe_area.har                          # har 包
│   └── safe_area                              # 鸿蒙适配核心代码
│       ├── index.ets                          # 鸿蒙适配代码入口
│       ├── ts.ts                              # Package / TurboModule 导出
│       └── src/main
│           ├── ets
│           │   ├── SafeAreaView.ets           # SafeAreaView 组件
│           │   ├── SafeAreaProvider.ets       # SafeAreaProvider 组件
│           │   ├── SafeAreaViewPackage.ts     # 鸿蒙 Package
│           │   ├── SafeViewTurboModule.ts     # RNCSafeAreaContext TurboModule
│           │   ├── SafeAreaViewModifier.ets   # SafeAreaView 属性修饰器
│           │   ├── SafeAreaProviderModifier.ets # SafeAreaProvider 属性修饰器
│           │   ├── Logger.ts                  # 日志工具
│           │   └── common
│           │       └── SafeAreaType.ts        # 安全区域类型定义
│           └── cpp
│               ├── CMakeLists.txt             # 原生构建配置
│               ├── SafeAreaViewPackage.h      # C++ Package
│               ├── SafeAreaViewComponentInstance.h/.cpp      # SafeAreaView 组件实例
│               ├── SafeAreaProviderComponentInstance.h/.cpp  # SafeAreaProvider 组件实例
│               ├── SafeAreaStackNode.h/.cpp   # Stack 节点
│               ├── SafeAreaColumnNode.h/.cpp  # Column 节点
│               ├── SafeAreaManagerMap.h/.cpp  # 组件实例映射
│               ├── TurboModuleRequest.h/.cpp  # TurboModule 请求
│               ├── SafeAreaBeanData.h         # 数据 Bean
│               └── generated                  # Codegen 生成代码
├── src                                        # RN 代码
│   ├── index.tsx                              # 入口文件
│   ├── SafeArea.types.ts                      # 类型文件
│   ├── SafeAreaView.tsx                       # SafeAreaView 组件
│   └── specs
│       ├── NativeSafeAreaContext.ts           # NativeSafeAreaContext 类型定义
│       ├── NativeSafeAreaProvider.ts          # NativeSafeAreaProvider 类型定义
│       └── NativeSafeAreaView.ts              # NativeSafeAreaView 类型定义
├── example                                    # 示例工程
├── CHANGELOG.md                               # 版本变更记录
├── README_en.md                               # 英文安装使用方法
└── README.md                                  # 中文安装使用方法

贡献代码

使用过程中发现任何问题都可以提交 Issue,当然,也非常欢迎提交 PR

开源协议

本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。

项目介绍

基于 react-native-safe-area-context 的 OpenHarmony 适配版,用于获取设备安全区域(刘海屏、状态栏、底部导航栏)的 insets 信息

定制我的领域