ReactNative项目OpenHarmony三方库集成实战:react-native-orientation-locker
屏幕方向控制是移动应用开发中的常见需求,特别是在视频播放、游戏、全屏图片浏览等场景中,需要根据内容类型动态调整屏幕方向。是一个功能强大的屏幕方向控制库,支持锁定屏幕方向、监听方向变化、获取当前方向等功能,是开发横竖屏切换应用的必备工具。库名称版本信息: 支持 RN 0.72 版本(已废弃)1.7.1+: 支持 RN 0.72/0.77 版本官方仓库鸿蒙仓库主要功能📱 锁定屏幕方向(竖屏、横屏、左
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

📋 前言
屏幕方向控制是移动应用开发中的常见需求,特别是在视频播放、游戏、全屏图片浏览等场景中,需要根据内容类型动态调整屏幕方向。react-native-orientation-locker 是一个功能强大的屏幕方向控制库,支持锁定屏幕方向、监听方向变化、获取当前方向等功能,是开发横竖屏切换应用的必备工具。
🎯 库简介
基本信息
- 库名称:
react-native-orientation-locker - 版本信息:
1.7.0-0.0.7+@react-native-oh-tpl/react-native-orientation-locker: 支持 RN 0.72 版本(已废弃)1.7.1++@react-native-ohos/react-native-orientation-locker: 支持 RN 0.72/0.77 版本
- 官方仓库: https://github.com/wonday/react-native-orientation-locker
- 鸿蒙仓库: https://atomgit.com/openharmony-sig/rntpc_react-native-orientation-locker
- 主要功能:
- 📱 锁定屏幕方向(竖屏、横屏、左横屏、右横屏)
- 🔄 监听屏幕方向变化
- 🔓 解锁屏幕方向,允许自由旋转
- 📐 获取当前设备方向
- 🎯 支持方向锁定状态监听
为什么需要屏幕方向控制库?
| 特性 | 原生开发 | react-native-orientation-locker |
|---|---|---|
| 方向锁定 | ⚠️ 需调用原生API | ✅ 统一接口 |
| 方向监听 | ⚠️ 需原生模块 | ✅ 事件回调机制 |
| 跨平台一致性 | ⚠️ iOS/Android差异 | ✅ 统一行为 |
| Hook支持 | ❌ 需自行实现 | ✅ 内置useOrientationChange |
| HarmonyOS 支持 | ❌ 无 | ✅ 完善适配 |
核心功能
| 功能 | 说明 | HarmonyOS 支持 |
|---|---|---|
| lockToPortrait() | 锁定为竖屏 | ✅ |
| lockToLandscape() | 锁定为横屏 | ✅ |
| lockToLandscapeLeft() | 锁定为左横屏 | ✅ |
| lockToLandscapeRight() | 锁定为右横屏 | ✅ |
| lockToPortraitUpsideDown() | 锁定为倒置竖屏 | ✅ |
| unlockAllOrientations() | 解锁所有方向 | ✅ |
| getOrientation() | 获取当前UI方向 | ✅ |
| getDeviceOrientation() | 获取设备物理方向 | ✅ |
| addOrientationListener() | 添加方向变化监听 | ✅ |
| addDeviceOrientationListener() | 添加设备方向监听 | ✅ |
| addLockListener() | 添加锁定状态监听 | ✅ |
兼容性验证
在以下环境验证通过:
- RNOH: 0.72.90; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.2; ROM: 6.0.0
📦 安装步骤
1. 安装依赖
请到三方库的 Releases 发布地址查看配套的版本信息:
| 三方库版本 | 发布信息 | 支持 RN 版本 |
|---|---|---|
| 1.7.0-0.0.7 | @react-native-oh-tpl/react-native-orientation-locker | 0.72(已废弃) |
| 1.7.1+ | @react-native-ohos/react-native-orientation-locker | 0.72/0.77 |

# RN 0.72 版本(推荐使用新版本)
npm install @react-native-ohos/react-native-orientation-locker@1.7.1-rc.1
# RN 0.77 版本
npm install @react-native-ohos/react-native-orientation-locker@1.8.0-rc.1
# 或者使用 yarn
yarn add @react-native-ohos/react-native-orientation-locker
2. 验证安装
安装完成后,检查 package.json 文件:
{
"dependencies": {
"@react-native-ohos/react-native-orientation-locker": "^1.7.1-rc.1"
}
}
🔧 HarmonyOS 平台配置 ⭐
1. 在工程根目录的 oh-package.json5 添加 overrides 字段(看自己package.json中的版本)
打开 harmony/oh-package.json5,添加以下配置:
{
// ... 其他配置
"overrides": {
"@rnoh/react-native-openharmony": "0.72.90"
}
}
2. 引入原生端代码
打开 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
3. 配置 CMakeLists
打开 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")
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
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
4. 引入 OrientationLockerPackage
打开 entry/src/main/cpp/PackageProvider.cpp,添加:
#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.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<RNOHGeneratedPackage>(ctx),
std::make_shared<SamplePackage>(ctx),
+ std::make_shared<OrientationLockerPackage>(ctx),
};
}
5. 在 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 SamplePackage(ctx),
new RNOrientationLockerPackage(ctx)
];
}
6. 配置权限
由于此库获取加速度传感器的数据,使用时需要配置对应的权限。在 entry/src/main/module.json5 中添加:
{
// ... 其他配置
"requestPermissions": [
{
"name": "ohos.permission.ACCELEROMETER"
}
]
}
然后编译、运行即可。
📖 API 详解
lockToPortrait - 锁定为竖屏
将应用锁定为竖屏模式,设备旋转时屏幕不会跟随旋转。
类型:() => void
使用场景:
- 阅读类应用
- 表单填写页面
- 列表浏览页面
import Orientation from 'react-native-orientation-locker';
// 锁定为竖屏
const lockPortrait = () => {
Orientation.lockToPortrait();
};
lockToLandscape - 锁定为横屏
将应用锁定为横屏模式,自动选择左横屏或右横屏。
类型:() => void
使用场景:
- 视频播放
- 游戏应用
- 图片浏览
import Orientation from 'react-native-orientation-locker';
// 锁定为横屏
const lockLandscape = () => {
Orientation.lockToLandscape();
};
lockToLandscapeLeft / lockToLandscapeRight - 锁定特定横屏方向
锁定为指定的横屏方向(左横屏或右横屏)。
类型:() => void
使用场景:
- 特定方向的视频播放
- 需要固定横屏方向的游戏
- 双人同屏游戏
import Orientation from 'react-native-orientation-locker';
// 锁定为左横屏(Home键在右侧)
Orientation.lockToLandscapeLeft();
// 锁定为右横屏(Home键在左侧)
Orientation.lockToLandscapeRight();
lockToPortraitUpsideDown - 锁定为倒置竖屏
将应用锁定为倒置竖屏模式。
类型:() => void
使用场景:
- 特殊展示需求
- 底部操作的应用
import Orientation from 'react-native-orientation-locker';
Orientation.lockToPortraitUpsideDown();
unlockAllOrientations - 解锁所有方向
解除屏幕方向锁定,允许设备自由旋转。
类型:() => void
使用场景:
- 退出全屏视频
- 恢复正常浏览模式
- 用户自主选择方向
import Orientation from 'react-native-orientation-locker';
// 解锁所有方向
const unlockOrientation = () => {
Orientation.unlockAllOrientations();
};
getOrientation - 获取当前UI方向
获取当前应用的UI方向(受锁定状态影响)。
类型:(callback: (orientation: string) => void) => void
返回值:
| 值 | 说明 |
|---|---|
| PORTRAIT | 竖屏 |
| LANDSCAPE-LEFT | 左横屏 |
| LANDSCAPE-RIGHT | 右横屏 |
| PORTRAIT-UPSIDEDOWN | 倒置竖屏 |
| UNKNOWN | 未知 |
使用场景:
- 根据方向调整UI布局
- 记录用户使用习惯
- 方向相关功能判断
import Orientation from 'react-native-orientation-locker';
Orientation.getOrientation((orientation) => {
console.log('当前UI方向:', orientation);
// PORTRAIT, LANDSCAPE-LEFT, LANDSCAPE-RIGHT, PORTRAIT-UPSIDEDOWN, UNKNOWN
});
getDeviceOrientation - 获取设备物理方向
获取设备实际的物理方向(不受锁定状态影响)。
类型:(callback: (orientation: string) => void) => void
使用场景:
- 检测用户握持方向
- 实现方向相关交互
- 传感器数据处理
import Orientation from 'react-native-orientation-locker';
Orientation.getDeviceOrientation((orientation) => {
console.log('设备物理方向:', orientation);
});
addOrientationListener - 添加方向变化监听
监听UI方向变化,当锁定方向时不会触发,直到解锁。
类型:(callback: (orientation: string) => void) => void
使用场景:
- 动态调整UI布局
- 方向变化动画
- 数据刷新
import Orientation, { useOrientationChange } from 'react-native-orientation-locker';
// 方式一:使用监听器
useEffect(() => {
const handleOrientationChange = (orientation) => {
console.log('方向变化:', orientation);
// 更新UI状态
};
Orientation.addOrientationListener(handleOrientationChange);
return () => {
Orientation.removeOrientationListener(handleOrientationChange);
};
}, []);
// 方式二:使用Hook
const MyComponent = () => {
useOrientationChange((orientation) => {
console.log('方向变化:', orientation);
});
return <View>...</View>;
};
addDeviceOrientationListener - 添加设备方向监听
监听设备物理方向变化,即使锁定方向也会触发。
类型:(callback: (orientation: string) => void) => void
使用场景:
- 实时检测设备姿态
- 游戏/AR应用
- 运动检测
import Orientation from 'react-native-orientation-locker';
useEffect(() => {
const handleDeviceOrientation = (orientation) => {
console.log('设备方向变化:', orientation);
};
Orientation.addDeviceOrientationListener(handleDeviceOrientation);
return () => {
Orientation.removeDeviceOrientationListener(handleDeviceOrientation);
};
}, []);
addLockListener - 添加锁定状态监听
监听方向锁定状态的变化。
类型:(callback: (orientation: string) => void) => void
返回值:
| 值 | 说明 |
|---|---|
| PORTRAIT | 锁定为竖屏 |
| LANDSCAPE-LEFT | 锁定为左横屏 |
| LANDSCAPE-RIGHT | 锁定为右横屏 |
| UNKNOWN | 未锁定(自由旋转) |
使用场景:
- 显示当前锁定状态
- 锁定状态UI提示
- 状态同步
import Orientation, { useLockListener } from 'react-native-orientation-locker';
// 方式一:使用监听器
useEffect(() => {
const handleLockChange = (orientation) => {
if (orientation === 'UNKNOWN') {
console.log('屏幕方向已解锁');
} else {
console.log('屏幕已锁定为:', orientation);
}
};
Orientation.addLockListener(handleLockChange);
return () => {
Orientation.removeLockListener(handleLockChange);
};
}, []);
// 方式二:使用Hook
const MyComponent = () => {
useLockListener((orientation) => {
console.log('锁定状态:', orientation);
});
return <View>...</View>;
};
OrientationLocker 组件
提供声明式的方向控制组件,适合在特定场景使用。
属性:
| 属性 | 类型 | 说明 |
|---|---|---|
| orientation | string | 锁定的方向类型 |
| onChange | function | 方向变化回调 |
| onDeviceChange | function | 设备方向变化回调 |
使用场景:
- 视频播放页面
- 全屏图片查看
- 游戏界面
import { OrientationLocker, PORTRAIT, LANDSCAPE } from 'react-native-orientation-locker';
const VideoPlayer = ({ isFullscreen }) => {
return (
<View>
<OrientationLocker
orientation={isFullscreen ? LANDSCAPE : PORTRAIT}
onChange={(orientation) => {
console.log('方向变化:', orientation);
}}
/>
{/* 视频播放器内容 */}
</View>
);
};
📋 完整示例

import React, { useCallback, useEffect, useState } from "react";
import {
Alert,
StyleSheet,
Text,
TouchableOpacity,
View,
ScrollView,
} from "react-native";
import Orientation, {
OrientationLocker,
PORTRAIT,
LANDSCAPE,
LANDSCAPE_LEFT,
LANDSCAPE_RIGHT,
PORTRAIT_UPSIDE_DOWN,
useOrientationChange,
useDeviceOrientationChange,
useLockListener,
} from "react-native-orientation-locker";
const App: React.FC = () => {
const [orientation, setOrientation] = useState<string>("未知");
const [deviceOrientation, setDeviceOrientation] = useState<string>("未知");
const [lockStatus, setLockStatus] = useState<string>("未锁定");
const [isFullscreen, setIsFullscreen] = useState(false);
useEffect(() => {
getOrientation();
}, []);
useOrientationChange((ori) => {
setOrientation(ori);
console.log("UI方向变化:", ori);
});
useDeviceOrientationChange((ori) => {
setDeviceOrientation(ori);
console.log("设备方向变化:", ori);
});
useLockListener((ori) => {
setLockStatus(ori === "UNKNOWN" ? "未锁定" : `已锁定: ${ori}`);
console.log("锁定状态变化:", ori);
});
const getOrientation = () => {
Orientation.getOrientation((ori) => {
if (ori) {
setOrientation(ori);
Alert.alert("当前屏幕方向", `UI方向: ${ori}`);
} else {
Alert.alert("获取失败", "无法获取当前屏幕方向");
}
});
};
const getDeviceOrientation = () => {
Orientation.getDeviceOrientation((ori) => {
if (ori) {
setDeviceOrientation(ori);
Alert.alert("当前设备方向", `设备方向: ${ori}`);
}
});
};
const lockToPortrait = useCallback(() => {
Orientation.lockToPortrait();
Alert.alert("锁定成功", "已锁定为竖屏");
}, []);
const lockToLandscape = useCallback(() => {
Orientation.lockToLandscape();
Alert.alert("锁定成功", "已锁定为横屏");
}, []);
const lockToLandscapeLeft = useCallback(() => {
Orientation.lockToLandscapeLeft();
Alert.alert("锁定成功", "已锁定为左横屏");
}, []);
const lockToLandscapeRight = useCallback(() => {
Orientation.lockToLandscapeRight();
Alert.alert("锁定成功", "已锁定为右横屏");
}, []);
const lockToPortraitUpsideDown = useCallback(() => {
Orientation.lockToPortraitUpsideDown();
Alert.alert("锁定成功", "已锁定为倒置竖屏");
}, []);
const lockToAllButUpsideDown = useCallback(() => {
Orientation.lockToAllOrientationsButUpsideDown();
Alert.alert("锁定成功", "已锁定除倒置外的所有方向");
}, []);
const unlockAll = useCallback(() => {
Orientation.unlockAllOrientations();
Alert.alert("解锁成功", "已解锁所有方向");
}, []);
const toggleFullscreen = useCallback(() => {
setIsFullscreen((prev) => !prev);
}, []);
const getOrientationLabel = (ori: string) => {
const labels: Record<string, string> = {
PORTRAIT: "竖屏",
"LANDSCAPE-LEFT": "左横屏",
"LANDSCAPE-RIGHT": "右横屏",
"PORTRAIT-UPSIDEDOWN": "倒置竖屏",
UNKNOWN: "未知",
};
return labels[ori] || ori;
};
return (
<View style={styles.container}>
<OrientationLocker
orientation={isFullscreen ? LANDSCAPE : PORTRAIT}
onChange={(ori) => console.log("组件方向变化:", ori)}
/>
<View style={styles.header}>
<Text style={styles.title}>屏幕方向控制示例</Text>
</View>
<View style={styles.statusPanel}>
<View style={styles.statusRow}>
<Text style={styles.statusLabel}>UI方向:</Text>
<Text style={styles.statusValue}>{getOrientationLabel(orientation)}</Text>
</View>
<View style={styles.statusRow}>
<Text style={styles.statusLabel}>设备方向:</Text>
<Text style={styles.statusValue}>{getOrientationLabel(deviceOrientation)}</Text>
</View>
<View style={styles.statusRow}>
<Text style={styles.statusLabel}>锁定状态:</Text>
<Text style={styles.statusValue}>{lockStatus}</Text>
</View>
</View>
<ScrollView style={styles.buttonContainer}>
<View style={styles.buttonGroup}>
<Text style={styles.groupTitle}>方向锁定</Text>
<TouchableOpacity style={styles.button} onPress={lockToPortrait}>
<Text style={styles.buttonText}>锁定竖屏</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={lockToLandscape}>
<Text style={styles.buttonText}>锁定横屏</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={lockToLandscapeLeft}>
<Text style={styles.buttonText}>锁定左横屏</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={lockToLandscapeRight}>
<Text style={styles.buttonText}>锁定右横屏</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={lockToPortraitUpsideDown}>
<Text style={styles.buttonText}>锁定倒置竖屏</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={lockToAllButUpsideDown}>
<Text style={styles.buttonText}>锁定除倒置外所有方向</Text>
</TouchableOpacity>
</View>
<View style={styles.buttonGroup}>
<Text style={styles.groupTitle}>解锁与查询</Text>
<TouchableOpacity style={[styles.button, styles.unlockButton]} onPress={unlockAll}>
<Text style={styles.buttonText}>解锁所有方向</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={getOrientation}>
<Text style={styles.buttonText}>获取UI方向</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={getDeviceOrientation}>
<Text style={styles.buttonText}>获取设备方向</Text>
</TouchableOpacity>
</View>
<View style={styles.buttonGroup}>
<Text style={styles.groupTitle}>全屏模式演示</Text>
<TouchableOpacity
style={[styles.button, isFullscreen && styles.activeButton]}
onPress={toggleFullscreen}
>
<Text style={styles.buttonText}>
{isFullscreen ? "退出全屏" : "进入全屏(横屏)"}
</Text>
</TouchableOpacity>
</View>
</ScrollView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#F5F5F5",
},
header: {
padding: 16,
backgroundColor: "#007AFF",
alignItems: "center",
},
title: {
fontSize: 18,
fontWeight: "600",
color: "#FFF",
},
statusPanel: {
backgroundColor: "#FFF",
padding: 16,
borderBottomWidth: 1,
borderBottomColor: "#E5E5EA",
},
statusRow: {
flexDirection: "row",
justifyContent: "space-between",
marginBottom: 8,
},
statusLabel: {
fontSize: 14,
color: "#666",
},
statusValue: {
fontSize: 14,
fontWeight: "500",
color: "#333",
},
buttonContainer: {
flex: 1,
padding: 16,
},
buttonGroup: {
marginBottom: 24,
},
groupTitle: {
fontSize: 16,
fontWeight: "600",
color: "#333",
marginBottom: 12,
},
button: {
backgroundColor: "#007AFF",
paddingVertical: 14,
paddingHorizontal: 20,
borderRadius: 8,
marginBottom: 10,
alignItems: "center",
},
unlockButton: {
backgroundColor: "#34C759",
},
activeButton: {
backgroundColor: "#FF9500",
},
buttonText: {
color: "#FFF",
fontSize: 16,
fontWeight: "500",
},
});
export default App;
⚠️ 注意事项
权限配置
使用此库需要配置加速度传感器权限,否则方向检测功能无法正常工作:
// entry/src/main/module.json5
{
"requestPermissions": [
{
"name": "ohos.permission.ACCELEROMETER"
}
]
}
方向常量
库提供了以下方向常量,方便代码中使用:
import {
PORTRAIT, // 竖屏
LANDSCAPE, // 横屏
LANDSCAPE_LEFT, // 左横屏
LANDSCAPE_RIGHT, // 右横屏
PORTRAIT_UPSIDE_DOWN, // 倒置竖屏
} from 'react-native-orientation-locker';
监听器清理
使用监听器时,务必在组件卸载时移除监听,避免内存泄漏:
useEffect(() => {
Orientation.addOrientationListener(handleOrientation);
return () => {
Orientation.removeOrientationListener(handleOrientation);
};
}, []);
更多推荐



所有评论(0)