基于 react-native-orientation-locker 的 OpenHarmony 适配版,屏幕方向锁定与监听
文档模板:v0.4.2
react-native-orientation-locker
本项目基于 react-native-orientation-locker 开发。
该第三方库的仓库已迁移至 Gitcode,并支持直接从 npm 下载,新包名为:@react-native-ohos/react-native-orientation-locker。版本归属关系如下:
| 三方库名称 | 三方库版本(npm地址) | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | 源码地址 |
|---|---|---|---|---|---|---|---|
| @react-native-ohos/react-native-orientation-locker | ~1.9.0 | Gitcode Releases | 0.82.* / 0.84.* | 是 | API12+ | 1.7.0 | master |
| @react-native-ohos/react-native-orientation-locker | ~1.8.0 | Gitcode Releases | 0.77.* | 否 | API12+ | 1.7.0 | br_rnoh0.77 |
| @react-native-ohos/react-native-orientation-locker | ~1.7.1 | Gitcode Releases | 0.72.* | 否 | API12+ | 1.7.0 | br_rnoh0.72 |
| @react-native-oh-tpl/react-native-orientation-locker | <= 1.7.0-0.0.7@deprecated | Github Releases | 0.72.* | 否 | API12+ | 1.7.0 | sig |
简介
react-native-orientation-locker 是一款 React Native 库,可监听设备方向变化、获取当前屏幕方向,并将屏幕锁定至首选方向。
下载安装
进入工程目录,并输入以下命令:
npm
npm install @react-native-ohos/react-native-orientation-locker
yarn
yarn add @react-native-ohos/react-native-orientation-locker
链接
| 是否支持 AutoLink | RN 框架版本 | |
|---|---|---|
| ~1.9.0 | 支持 | 0.82/0.84 |
使用 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.84.30" // 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-orientation-locker":"file:../../node_modules/@react-native-ohos/react-native-orientation-locker/harmony/orientation_locker.har"
}
点击右上角的 sync 按钮
或者在命令行终端执行:
cd entry
ohpm install
方法二:直接链接源码
如需使用直接链接源码,请参见[直接链接源码说明](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/link-source-code.md)
3. 配置 CMakeLists 并引入 OrientationLockerPackage
打开 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-orientation-locker/src/main/cpp" ./orientation_locker)
# 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_orientation_locker)
# RNOH_END: manual_package_linking_2
请打开 entry/src/main/cpp/PackageProvider.cpp,并添加:
#include "RNOH/PackageProvider.h"
#include "SamplePackage.h"
+ #include "OrientationLockerPackage.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
std::make_shared<SamplePackage>(ctx),
+ std::make_shared<OrientationLockerPackage>(ctx),
};
}
4. 在 ArkTs 端引入 RNOrientationLockerPackage
打开 entry/src/main/ets/RNPackagesFactory.ts,添加:
...
+ import { RNOrientationLockerPackage } from '@react-native-ohos/react-native-orientation-locker/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
+ new RNOrientationLockerPackage(ctx)
];
}
运行
点击右上角的 sync 按钮
或者在命令行终端中执行:
cd entry
ohpm install
然后进行编译并运行即可。
约束与限制
兼容性
本文档内容已在以下版本中验证通过:
- RNOH: 0.82.1;SDK: HarmonyOS 6.0.1 Release SDK;IDE: DevEco Studio 6.0.1 Release;ROM: 6.0.0.328 SP52;
- RNOH: 0.84.30;SDK: HarmonyOS 6.0.1 Release SDK;IDE: DevEco Studio 6.0.1 Release;ROM: 6.0.0.328 SP52;
权限要求
由于该库需要获取加速度传感器数据,使用时需配置相应权限,请在 entry/src/main 目录下的 module.json5 文件中添加如下权限:
...
"requestPermissions": [
...
+ {
+ "name": "ohos.permission.ACCELEROMETER"
+ }
]
使用示例
以下代码展示了该库的基本使用场景:
使用时,import 的库名保持不变。
import React, { useState } from "react";
import { View, Text, TouchableOpacity } from "react-native";
import Orientation from "react-native-orientation-locker";
const App = () => {
const [orientation, setOrientation] = useState("");
const getOrientation = () => {
Orientation.getOrientation((ori) => setOrientation(ori));
};
return (
<View style={{ flex: 1 }}>
<Text>当前方向: {orientation}</Text>
<TouchableOpacity onPress={() => Orientation.lockToPortrait()}>
<Text>锁定竖屏</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => Orientation.lockToLandscape()}>
<Text>锁定横屏</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => Orientation.unlockAllOrientations()}>
<Text>解锁旋转</Text>
</TouchableOpacity>
<TouchableOpacity onPress={getOrientation}>
<Text>获取当前方向</Text>
</TouchableOpacity>
</View>
);
};
export default App;
使用说明
基本用法
import Orientation from 'react-native-orientation-locker';
// 锁定为竖屏
Orientation.lockToPortrait();
// 锁定为横屏
Orientation.lockToLandscape();
// 解锁,允许自由旋转
Orientation.unlockAllOrientations();
// 获取当前 UI 方向(回调)
Orientation.getOrientation((orientation) => {
console.log('当前方向:', orientation);
});
// 判断当前是否已锁定
const locked = Orientation.isLocked();
Hooks 用法
import React from 'react';
import {
useOrientationChange,
useDeviceOrientationChange,
useLockListener,
} from 'react-native-orientation-locker';
const App = () => {
useOrientationChange((orientation) => {
console.log('UI 方向变化:', orientation);
});
useDeviceOrientationChange((deviceOrientation) => {
console.log('设备物理方向变化:', deviceOrientation);
});
useLockListener((orientation) => {
console.log('锁定状态变化:', orientation);
});
return <Text>方向监听示例</Text>;
};
事件监听
import React from 'react';
import Orientation from 'react-native-orientation-locker';
const App = () => {
React.useEffect(() => {
const listener = (orientation) => {
console.log('UI 方向变化:', orientation);
};
Orientation.addOrientationListener(listener);
return () => {
Orientation.removeOrientationListener(listener);
};
}, []);
return <Text>方向监听示例</Text>;
};
接口说明
“Platform”列表示该属性在原三方库中支持的平台。
“OpenHarmony Support”列取值为 yes 表示 OpenHarmony 平台支持该属性;no 表示不支持;partially 表示部分支持。各平台的使用方法保持一致,效果对标 iOS 或 Android。
API
| Name | Description | Type | Required | Platform | HarmonyOS Support |
|---|---|---|---|---|---|
| lockToPortrait | 将应用方向锁定为竖屏(portrait) | function | No | IOS/Android | yes |
| lockToLandscape | 将应用方向锁定为横屏(landscape) | function | No | IOS/Android | yes |
| lockToLandscapeLeft | 将应用方向锁定为左侧横屏 | function | No | IOS/Android | yes |
| lockToLandscapeRight | 将应用方向锁定为右侧横屏 | function | No | IOS/Android | yes |
| lockToPortraitUpsideDown | 将应用方向锁定为倒置竖屏 | function | No | IOS/Android | yes |
| lockToAllOrientationsButUpsideDown | 锁定为除倒置竖屏以外的所有方向 | function | No | IOS/Android | yes |
| unlockAllOrientations | 解锁应用方向,允许设备自由旋转 | function | No | IOS/Android | yes |
| getOrientation | 获取当前 UI 方向 | function | No | IOS/Android | yes |
| getDeviceOrientation | 获取当前设备物理方向 | function | No | IOS/Android | yes |
| getInitialOrientation | 获取应用初始方向 | function | No | IOS/Android | yes |
| isLocked | 返回当前方向是否处于锁定状态 | function | No | IOS/Android | yes |
| getAutoRotateState1.9.0 | 获取设备自动旋转状态 | function | No | Android | yes |
| configure1.9.0 | 配置方向检测相关选项 | function | No | IOS | yes |
事件
| Name | Description | Type | Required | Platform | HarmonyOS Support |
|---|---|---|---|---|---|
| addOrientationListener | 当 UI 方向发生变化时触发回调。回调返回值可能为 PORTRAIT、LANDSCAPE-LEFT、LANDSCAPE-RIGHT、PORTRAIT-UPSIDEDOWN、UNKNOWN | callback | No | IOS/Android | yes |
| addDeviceOrientationListenerchanged in 1.9.0 | 当设备物理方向发生变化时触发回调。回调返回值可能为 PORTRAIT、LANDSCAPE-LEFT、LANDSCAPE-RIGHT、PORTRAIT-UPSIDEDOWN、FACE-UP、FACE-DOWN、UNKNOWN(其中 FACE-UP、FACE-DOWN 为 1.9.0 新增) | callback | No | IOS/Android | yes |
| removeOrientationListener | 移除之前添加的 UI 方向变化监听 | callback | No | IOS/Android | yes |
| removeDeviceOrientationListener | 移除设备物理方向变化监听 | callback | No | IOS/Android | yes |
| addLockListener | 添加屏幕方向锁定状态变化监听。回调返回值可能为 PORTRAIT、LANDSCAPE-LEFT、LANDSCAPE-RIGHT、UNKNOWN,其中 UNKNOWN 表示未锁定。 | callback | No | IOS/Android | yes |
| removeLockListener | 移除屏幕方向锁定状态变化监听 | callback | No | IOS/Android | yes |
| removeAllListeners | 移除所有监听事件 | callback | No | IOS/Android | yes |
Hooks
| Name | Description | Type | Required | Platform | HarmonyOS Support |
|---|---|---|---|---|---|
| useOrientationChange | 用于监听 UI 方向变化的 Hook。 | hook | No | IOS/Android | yes |
| useDeviceOrientationChange | 用于监听设备物理方向变化的 Hook。 | hook | No | IOS/Android | yes |
| useLockListener | 用于监听方向锁定状态变化的 Hook。 | hook | No | IOS/Android | yes |
组件
OrientationLocker
声明式方向锁定组件,通过 props 控制屏幕方向锁定。
| Props | 描述 | 类型 | 必填 | 平台 | HarmonyOS 支持 |
|---|---|---|---|---|---|
| orientation | 要锁定到的方向。可选值:UNLOCK、PORTRAIT、LANDSCAPE、LANDSCAPE_LEFT、LANDSCAPE_RIGHT、PORTRAIT_UPSIDE_DOWN、ALL_ORIENTATIONS_BUT_UPSIDE_DOWN | string | 否 | IOS/Android | 是 |
| onChange | UI 方向变化时的回调 | function | 否 | IOS/Android | 是 |
| onDeviceChange | 设备物理方向变化时的回调 | function | 否 | IOS/Android | 是 |
遗留问题
其他
无
目录结构
/rntpc_react-native-orientation-locker # 项目根目录
├── harmony # 鸿蒙适配代码
│ ├── orientation_locker.har # har 包
│ └── orientation_locker # 鸿蒙适配核心代码
│ ├── Index.ets # 鸿蒙适配代码入口
│ └── src/main
│ ├── cpp # C++ 原生模块
│ │ └── OrientationLockerPackage.h
│ └── ets # ArkTS 代码
│ ├── RNOrientationLockerPackage.ets # 包注册
│ ├── RNOrientationLockerTurboModule.ts # 原生模块实现
│ └── generated # 生成的 TurboModule 代码
├── src # RN 代码
│ ├── orientation.js # 方向监听/锁定核心逻辑
│ ├── orientation.harmony.js # 鸿蒙平台实现
│ ├── orientation.android.js # Android 平台实现
│ ├── orientation.ios.js # iOS 平台实现
│ ├── OrientationLocker.js # 声明式方向锁定组件
│ └── hooks # Hooks 实现
│ ├── index.js
│ ├── useOrientationChange.js
│ ├── useDeviceOrientationChange.js
│ └── useLockListener.js
├── index.js # 入口文件
├── index.d.ts # 类型定义
├── README_en.md # 英文文档
└── README.md # 中文文档
贡献代码
在使用过程中发现任何问题,都可以提交 Issue,同时也欢迎提交 PR 。
开源协议
本项目基于 The MIT License (MIT) ,欢迎自由使用与参与开源。