rntpc_react-native-orientation-locker:基于 react-native-orientation-locker 的 OpenHarmony 适配版,屏幕方向锁定与监听

基于 react-native-orientation-locker 的 OpenHarmony 适配版,屏幕方向锁定与监听

分支4Tags9
当前项目代码仓暂无内容

文档模板: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

然后进行编译并运行即可。

约束与限制

兼容性

本文档内容已在以下版本中验证通过:

  1. RNOH: 0.82.1;SDK: HarmonyOS 6.0.1 Release SDK;IDE: DevEco Studio 6.0.1 Release;ROM: 6.0.0.328 SP52;
  2. 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) ,欢迎自由使用与参与开源。

项目介绍

基于 react-native-orientation-locker 的 OpenHarmony 适配版,屏幕方向锁定与监听

定制我的领域