react-native-navigation:基于 React Native for OpenHarmony 的原生页面导航项目

导航路由开发组件,实现导航能力相关组件

Branch3Tags2

react-native-navigation

本项目基于 react-native-navigation 开发,并适配 React Native for OpenHarmony。 如果在使用过程中有任何问题,可以在 GitCode 提交 Issue,我们会及时跟进。

项目介绍

@hxa-rn/react-native-navigation 是 react-native-navigation@8.8.11 的 React Native for OpenHarmony 适配包,为 React Native 应用提供基于 HarmonyOS 原生容器的页面导航能力。

适配后实际支持的主要能力包括:

  • 注册 React Native 页面,并通过根布局创建 component、stack、bottomTabs、topTabs、sideMenu 和 splitView 布局。
  • 执行 push、pop、popTo、popToRoot 和 setStackRoot 页面栈操作。
  • 展示和关闭 Modal、Overlay 及 Bottom Tabs,并支持 interceptTouchOutside 等已适配选项。
  • 设置默认导航选项、合并已挂载页面的选项,以及更新页面属性。
  • 获取 HarmonyOS 窗口度量相关常量和应用启动参数。
  • 通过 JavaScript 路由管线配置、解析和处理 Deep Link。
  • 监听应用启动、页面生命周期、命令完成、Bottom Tab 选择、Modal 关闭和页面弹出等已适配事件。
  • 提供 Fabric Modal 组件及 visible、transparent、blurOnUnmount、animationType、onShow 和 onRequestClose 属性。

集成指南

安装

在 React Native 工程根目录执行:

npm install @hxa-rn/react-native-navigation

本包需要宿主工程满足以下 peer 依赖:react >= 18、react-native >= 0.72、remx(可选,3.x.x)。安装后使用与项目配置匹配的 React Native for OpenHarmony 和 HarmonyOS SDK 版本。

Autolinking

本包支持 Autolinking。安装依赖后由宿主工程自动接入,无需手动注册。

导入

import {Modal, Navigation} from '@hxa-rn/react-native-navigation';

使用说明

基础用法

import React, {useEffect} from 'react';
import {Text, View} from 'react-native';
import {Navigation} from '@hxa-rn/react-native-navigation';

const HOME = 'NavigationExample.Home';

function HomeScreen({componentId}: {componentId: string}) {
  return (
    <View>
      <Text>componentId: {componentId}</Text>
    </View>
  );
}

Navigation.registerComponent(HOME, () => HomeScreen);

export default function App() {
  useEffect(() => {
    Navigation.setRoot({
      root: {
        stack: {
          children: [{component: {name: HOME}}],
        },
      },
    });
  }, []);

  return <View />;
}

页面名称必须先通过 Navigation.registerComponent 注册,并且每个页面名称应保持唯一。页面级接口需要传入有效的 componentId。setRoot、页面栈、Modal 和 Overlay 的 Promise 在命令完成或操作失败时反映对应结果。

await Navigation.push(componentId, {
  component: {
    name: 'NavigationExample.Details',
    passProps: {source: componentId},
  },
});

const subscription = Navigation.events().registerCommandCompletedListener(
  event => {
    console.info(event.commandName, event.commandId);
  },
);

Navigation.setLinking({
  prefixes: ['rnnexample://'],
  config: {
    screens: {
      'NavigationExample.Details': 'details/:id',
    },
  },
  fallback: url => console.warn(`未匹配的 Deep Link: ${url}`),
});

const match = Navigation.resolveDeepLink('rnnexample://details/42');
Navigation.handleDeepLink('rnnexample://details/42');

subscription.remove();

Navigation.events() 返回事件注册器,订阅对象提供 remove() 方法。Deep Link 的 URL 匹配、路径参数、query 参数、延迟队列和路由执行由 JavaScript 路由管线处理;系统级 URL 拉起仍需要宿主应用自行配置对应的 scheme、host 或应用链接能力。

接口文档

以下接口来自本包实际导出的 Navigation、EventsRegistry 和 Modal,其中原生侧仅对适配报告和源码确认的能力作支持声明。

Navigation 导出对象提供以下接口:

接口 类型 默认值 说明
registerComponent (componentName: string | number, componentProvider: ComponentProvider, concreteComponentProvider?: ComponentProvider) => ComponentProvider 无 注册 React Native 页面组件。
setRoot (layout: LayoutRoot) => Promise<string> 无 设置或重置应用根布局。
setDefaultOptions (options: Options) => void 无 设置页面默认导航选项。
mergeOptions (componentId: string, options: Options) => void 无 合并已挂载页面的导航选项。HarmonyOS 原生侧已消费部分 Top Bar、Bottom Tab、Side Menu 和布局选项。
updateProps (componentId: string, props: object, callback?: () => void) => void 无 更新已挂载组件的属性。
push (componentId: string, layout: Layout) => Promise<string> 无 向页面所在 Stack 推入新布局。
pop (componentId: string, mergeOptions?: Options) => Promise<string> 无 从页面所在 Stack 移除页面。
popTo (componentId: string, mergeOptions?: Options) => Promise<string> 无 返回到指定页面。
popToRoot (componentId: string, mergeOptions?: Options) => Promise<string> 无 返回当前 Stack 的根页面。
setStackRoot (componentId: string, layout: Layout | Layout[]) => Promise<string> 无 替换当前 Stack 的根布局。
showModal (layout: Layout) => Promise<string> 无 展示命令式 Modal。
dismissModal (componentId: string, mergeOptions?: Options) => Promise<string> 无 关闭指定 Modal。
dismissAllModals (mergeOptions?: Options) => Promise<string> 无 关闭全部 Modal。
showOverlay (layout: Layout) => Promise<string> 无 展示 Overlay。
dismissOverlay (componentId: string) => Promise<string> 无 关闭指定 Overlay。
dismissAllOverlays () => Promise<string> 无 关闭全部 Overlay。
events () => EventsRegistry 无 获取事件注册器。
constants () => Promise<NavigationConstants> 无 异步获取 statusBarHeight、topBarHeight、bottomTabsHeight 和 backButtonId。
constantsSync () => NavigationConstants 无 同步获取导航常量。
getLaunchArgs () => Promise<any> 无 获取 HarmonyOS 原生入口传入的应用启动参数。
setLinking (config: LinkingConfig) => void 无 配置 Deep Link 前缀和 screens 路由。
handleDeepLink (url: string) => void 无 将 URL 交给 Deep Link 管线处理。
resolveDeepLink (url: string) => RouteMatch | null 无 解析 URL,不执行导航。
setLinkingReady (ready: boolean) => void 无 设置 Deep Link 处理就绪状态,并处理就绪前排队的链接。

EventsRegistry

Navigation.events() 返回的 EventsRegistry 提供以下已适配事件监听接口:

接口 类型 默认值 说明
registerAppLaunchedListener (callback: () => void) => EmitterSubscription 无 监听应用启动事件。
registerComponentWillAppearListener (callback: (event: ComponentWillAppearEvent) => void) => EmitterSubscription 无 监听页面即将出现。
registerComponentDidAppearListener (callback: (event: ComponentDidAppearEvent) => void) => EmitterSubscription 无 监听页面已经出现。
registerComponentDidDisappearListener (callback: (event: ComponentDidDisappearEvent) => void) => EmitterSubscription 无 监听页面消失。
registerCommandCompletedListener (callback: (event: CommandCompletedEvent) => void) => EmitterSubscription 无 监听导航命令完成。
registerBottomTabSelectedListener (callback: (event: BottomTabSelectedEvent) => void) => EmitterSubscription 无 监听 Bottom Tab 选择变化。
registerModalDismissedListener (callback: (event: ModalDismissedEvent) => void) => EmitterSubscription 无 监听 Modal 关闭。
registerScreenPoppedListener (callback: (event: ScreenPoppedEvent) => void) => EmitterSubscription 无 监听页面从 Stack 弹出。

registerBottomTabPressedListener、registerBottomTabLongPressedListener、导航按钮、搜索栏、预览及 registerModalAttemptedToDismissListener 等接口虽然保留在 JavaScript 类型导出中,但当前 HarmonyOS 适配不宣称其原生事件行为已实现,不应作为本适配包的已支持能力使用。

Modal 是通过 Fabric RNNModalViewManager 注册的组件。其主要属性如下:

属性 类型 默认值 说明
visible boolean 无 是否显示 Modal;该属性为必需属性。
transparent boolean false 是否使用透明背景。
blurOnUnmount boolean false 卸载时是否执行模糊相关处理。
animationType 'none' | 'fade' | 'slide' 'slide' Modal 动画类型。
onShow () => any 无 Modal 显示时回调。
onRequestClose () => any 无 请求关闭 Modal 时回调。

当前适配重点覆盖核心导航、布局渲染、事件链路和 Fabric Modal。完整的 Top Bar 按钮、搜索栏、系统栏、共享元素及平台专属高级转场等上游能力未宣称为 HarmonyOS 全量对等实现。

快速验证(运行 Example)

前置条件

依赖 版本要求
Node.js >=20
React Native for OpenHarmony 0.72.139
HarmonyOS SDK API 21+

运行步骤

  1. 获取开发分支源码:

    git clone -b react-native-navigation_dev https://gitcode.com/hxa-rn/react-native-navigation.git
    
  2. 进入仓库根目录:

    cd react-native-navigation
    
  3. 安装根目录依赖:

    npm i
    
  4. 生成供示例工程安装的本地安装包:

    npm pack
    
  5. 进入示例工程目录:

    cd example
    
  6. 安装示例工程依赖:

    npm i
    
  7. 生成 React Native JavaScript Bundle:

    npm run dev
    
  8. 使用 DevEco Studio 打开 example/harmony 工程,同步依赖、完成签名配置后构建运行。

约束与限制

兼容性

依赖 要求
React Native for OpenHarmony 0.72.139
HarmonyOS SDK API 21+
Example 工程 compatibleSdkVersion 6.0.1(21)
Example 工程 targetSdkVersion 6.1.1(24)
Node.js >=20

使用限制

  • 当前适配覆盖核心导航链路和 Example 中实际验证的页面布局;不能据此宣称 react-native-navigation@8.8.11 的全部 Options、事件、视觉转场和共享元素行为已在 HarmonyOS 上完全对等。
  • mergeOptions 的原生消费范围以当前适配实现为准,已确认包括部分 Top Bar、标题、可见性、Bottom Tab、customRow、Side Menu 和布局状态;复杂按钮、搜索栏、系统栏和高级转场选项不在完整对等承诺范围内。
  • Overlay 已实现展示、关闭和外部触摸拦截状态;interceptTouchOutside=false 时空白区域逐像素穿透到下层 React Surface 的行为需要在目标设备和宿主窗口结构上验收。
  • Deep Link 的 URL 解析和导航管线由本包处理;系统级 URL 拉起、scheme、host、skills 和域名关联必须由宿主应用配置。
  • HAP 签名材料不由本包提供,宿主工程需要按自身发布流程配置签名。
  • 页面必须先注册,页面级调用必须传入有效的 componentId;Autolinking 和手动注册不能重复使用。

系统权限

本包的 harmony/navigation/src/main/module.json5 中 requestPermissions 为空。导航、布局、事件、Modal、Overlay、Deep Link 解析和启动参数能力不要求本包声明额外的 user_grant 运行时权限。

开源 License

本项目采用 MIT License,与上游项目保持一致。

问题反馈渠道

如在使用过程中遇到问题,请在 GitCode 提交 Issue,我们会及时跟进。

  • 提交问题时建议附上项目版本、RN 版本、OpenHarmony SDK/API 版本、DevEco Studio 版本、设备信息、复现步骤及相关日志。
  • 涉及签名、账号、密钥或用户数据时,请勿在 Issue 中上传敏感信息;可按组织安全流程提交脱敏日志。

Introduction

导航路由开发组件,实现导航能力相关组件

Customize your domain