# rn_ohfeatures
**Repository Path**: openharmony-sig/rn_ohfeatures
## Basic Information
- **Project Name**: rn_ohfeatures
- **Description**: 这是一个旨在解决React Native页面与OpenHarmonyOS特性特征不一致问题,专为React Native页面提供OpenHarmony特征。该库包含的接口和开箱即用的组件,使开发者能够在React Native页面轻松应用各种OpenHarmony特征。
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: https://gitee.com/openharmony-sig/rn_ohfeatures
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2025-02-08
- **Last Updated**: 2025-05-07
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 🚨 **重要提示 | IMPORTANT**
>
> **⚠️ 此代码仓已归档。新地址请访问 [rn_ohfeatures](https://gitcode.com/openharmony-sig/rn_ohfeatures)。| ⚠️ This repository has been archived. For the new address, please visit [rn_ohfeatures](https://gitcode.com/openharmony-sig/rn_ohfeatures).**
>
---
>
# rn_hmfeatures
## 介绍
这是一个旨在解决React Native页面与OpenHarmonyOS特性特征不一致问题,专为React Native页面提供OpenHarmony特征。该库包含的接口和开箱即用的组件,使开发者能够在React Native页面轻松应用各种OpenHarmony特征。
## 工程目录
```
├─harmony
│ ├─rn_hmfeatures.har
│ └─rn_hmfeatures
│ └─src
│ └─main
│ └─cpp // OpenHarmony侧CAPI实现Fabric组件
│ ├─CMakeLists.txt
│ ├─GeometryViewComponentDescriptor.h
│ ├─GeometryViewComponentInstance.cpp
│ ├─GeometryViewComponentInstance.h
│ ├─GeometryViewEventEmitter.cpp
│ ├─GeometryViewEventEmitter.h
│ ├─GeometryViewJSIBinder.h
│ ├─GeometryViewNode.cpp
│ ├─GeometryViewNode.h
│ ├─GeometryViewPackage.cpp
│ ├─GeometryViewPackage.h
│ ├─Props.cpp
│ └─Props.h
└─src
├─index.tsx
└─fabric
└─GeometryView.tsx // RN 侧Fabric组件
```
## 安装与使用
请拉取[rn_hmfeatures](https://gitee.com/ohadss/rn_hmfeatures)代码仓并执行`npm pack`获取tgz包。
进入到工程目录并输入以下命令:
>**说明:**
>#处替换为tgz包的路径
**npm**
```bash
npm install rn_hmfeatures@file:#
```
**yarn**
```bash
yarn add rn_hmfeatures@file:#
```
下面的代码展示了这个库的基本使用场景:ArkUI的navigation控制路由跳转,NavDestination加载对应的RN bundle。
**PlayList页面**
使用了GeometryView组件,并设置了geometryViewID为'test',点击事件调用原生navPathStack.pushPath,跳转MusicPlay页面。
```jsx
function PlayList() {
return (
{
SampleTurboModule.pushStringToHarmony('pages/MusicPlay', 1);
}}
/>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
},
geometryView: {
position: 'absolute',
width: 60,
height: 60,
backgroundColor: 'red',
},
});
export default PlayList;
```
**MusicPlay页面**
```jsx
function MusicPlay() {
return (
{
SampleTurboModule.pushStringToHarmony('pop', 2)
}} >
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%'
},
text: {
fontSize: 18,
color: '#333',
},
});
export default MusicPlay;
```
**原生侧**
PlayListPage监听RN页面跳转事件,如果事件触发,调用this.navPathStack.pushPath({ name: 'MusicPlayPage' }),跳转至原生MusicPlayPage页面。
```ts
@Component
export default struct PlayListPage {
private instance: RNInstance = LoadManager.instance;
private bundlePath = 'bundle/playlist.harmony.bundle'
private moduleName = 'PlayList'
@StorageLink('isMetroAvailable') isMetroAvailable: boolean = false
@Consume('navPathStack') navPathStack: NavPathStack
aboutToAppear() {
emitter.on({ eventId: 1 }, () => {
animateTo({duration: 700, curve: Curve.Friction}, () => {
this.navPathStack.pushPath({ name: 'MusicPlayPage' })
});
});
}
aboutToDisappear() {
emitter.off(1);
}
build() {
NavDestination() {
if (this.isMetroAvailable) {
MetroBaseRN({
moduleName: this.moduleName,
}).align(Alignment.Top).margin({ top: 0 })
} else if (this.instance) {
BaseRN({
rnInstance: this.instance,
moduleName: this.moduleName,
bundlePath: this.bundlePath,
}).align(Alignment.Top).margin({ top: 0 })
} else {
Text('加载失败')
}
}
.hideTitleBar(true)
}
}
```
**MusicPlayPage加载RN侧MusicPlay页面**
```ts
@Component
export default struct MusicPlayPage {
private instance: RNInstance = LoadManager.instance
private bundlePath = 'bundle/musicplay.harmony.bundle'
private moduleName = 'MusicPlay'
@StorageLink('isMetroAvailable') isMetroAvailable: boolean = false
@Consume('navPathStack') navPathStack: NavPathStack
aboutToAppear() {
emitter.on({ eventId: 2 }, () => {
animateTo({duration: 700, curve: Curve.Friction}, () => {
this.navPathStack.pop()
});
});
}
aboutToDisappear() {
emitter.off(2);
}
build() {
NavDestination() {
if (this.isMetroAvailable) {
MetroBaseRN({
moduleName: this.moduleName,
})
.align(Alignment.Top).margin({ top: 20 })
} else if (this.instance) {
BaseRN({
rnInstance: this.instance,
moduleName: this.moduleName,
bundlePath: this.bundlePath,
}).align(Alignment.Top).margin({ top: 20 })
} else {
Text('加载失败')
}
}
.geometryTransition('test') // 设置同RN侧一致的id
.hideTitleBar(true)
}
}
```
## Link
目前OpenHarmony暂不支持AutoLink,所以Link步骤需要手动配置。
首先需要使用DevEco Studio打开项目里的OpenHarmony工程,在工程根目录的 `oh-package.json5` 添加 overrides 字段:
```json
{
...
"overrides": {
"@rnoh/react-native-openharmony" : "./react_native_openharmony"
}
}
```
### 引入原生端代码
目前有两种方法:
1. **通过har包引入(在IDE完善相关功能后该方法会被遗弃,目前首选此方法)。**
>**说明:**
>har包位于三方库安装路径的`harmony`文件夹下。
a.打开`entry/oh-package.json5`,添加以下依赖:
```json
"dependencies": {
"@rnoh/react-native-openharmony": "file:../react_native_openharmony",
"rn_hmfeatures": "file:../../node_modules/rn_hmfeatures/harmony/rn_hmfeatures.har",
}
```
b.配置CMakeLists和引入GeometryViewPackage:
打开`entry/src/main/cpp/CMakeLists.txt`,添加:
```diff
project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp")
set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
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")
add_compile_definitions(WITH_HITRACE_SYSTRACE)
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
+ add_subdirectory("${OH_MODULE_DIR}/rn_hmfeatures/src/main/cpp" ./rn_hmfeatures)
add_subdirectory("${RNOH_CPP_DIR}" ./rn)
add_library(rnoh_app SHARED
"./PackageProvider.cpp"
"${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)
+ target_link_libraries(rnoh_app PUBLIC rn_hmfeatures)
```
c.打开`entry/src/main/cpp/PackageProvider.cpp`,添加:
```diff
#include "RNOH/PackageProvider.h"
+ #include "GeometryViewPackage.h"
using namespace rnoh;
std::vector> PackageProvider::getPackages(Package::Context ctx) {
return {
+ std::make_shared(ctx)
};
}
```
d.运行:
点击右上角的`sync`按钮
或者在终端执行:
```bash
cd entry
ohpm install
```
然后编译、运行即可。
2. **直接链接源码。**
如需使用直接链接源码,请参考[直接链接源码说明](https://gitee.com/react-native-oh-library/usage-docs/blob/master/zh-cn/link-source-code.md)
## API
>**说明:**
>"Platform"列表示支持的平台,All表示支持所有平台。
| Name | Description | Type | Platform |
| ------------------- | --------------------- | -------- | ----------- |
| geometryViewID | 共享元素ID. | string | OpenHarmony |
| onGeometryViewClick | 点击GeometryView回调. | callback | OpenHarmony |