ReactNative for OpenHarmony项目鸿蒙化三方库:react-native-shake — 摇一摇事件监听
本文详细介绍了在 HarmonyOS 平台的使用方法。通过 Shake 组件,你可以轻松实现摇一摇交互功能。核心要点✅ 简单易用的 API 设计✅ 基于订阅模式的事件监听✅ 需要配置加速度计权限✅ 记得在组件卸载时移除监听希望本文能帮助你在 HarmonyOS 项目中顺利集成摇一摇功能!
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
📌 开发环境声明:本文基于 React Native 0.72.90 版本进行开发适配
🚀 一、开篇引言
摇一摇是移动应用中常见的交互方式,广泛应用于摇一摇抽奖、摇一摇换题、摇一摇反馈等场景。react-native-shake 是 React Native 社区中简单易用的摇一摇事件监听组件,可以检测用户摇晃手机的动作并触发相应事件。本文将带你深入了解如何在 HarmonyOS 平台上集成和使用这个有趣的交互组件。
1.1 大纲
- ✅ react-native-shake 的核心概念与工作原理
- ✅ HarmonyOS 平台的完整集成流程
- ✅ 摇一摇事件监听与处理
- ✅ API 的深度解析
- ✅ 实际应用场景的最佳实践
1.2 适用人群
- 正在进行 React Native 鸿蒙化迁移的开发者
- 需要实现摇一摇功能的开发者
- 对跨平台传感器组件开发感兴趣的技术爱好者
1.3 为什么选择 react-native-shake?
| 特点 | 说明 |
|---|---|
| 简单易用 | API 极简,几行代码即可实现 |
| 跨平台一致 | iOS、Android、HarmonyOS 表现一致 |
| 轻量级 | 无需复杂配置,开箱即用 |
| 事件驱动 | 基于订阅模式,灵活管理监听生命周期 |
| 低功耗 | 智能检测,不影响设备续航 |
📦 二、库概览
2.1 基本信息
| 项目 | 内容 |
|---|---|
| 库名称 | @react-native-ohos/react-native-shake |
| 原库名称 | react-native-shake |
| 版本信息 | 5.6.3 (RN 0.72) / 6.0.2 (RN 0.77) |
| 官方仓库 | https://github.com/Doko-Demo-Doa/react-native-shake |
| 鸿蒙仓库 | https://gitcode.com/openharmony-sig/rntpc_react-native-shake |
| 开源协议 | MIT |
2.2 版本兼容性
| 三方库版本 | 支持RN版本 | 是否支持Autolink |
|---|---|---|
| ~6.0.2 | 0.77 | No |
| ~5.6.3 | 0.72 | Yes |
| <=5.6.2-0.0.1@deprecated | 0.72 | No |
2.3 核心能力矩阵
| 能力项 | 描述 | HarmonyOS 支持 |
|---|---|---|
| 添加监听 | addListener 方法 | ✅ 完全支持 |
| 移除监听 | remove 方法 | ✅ 完全支持 |
| 移除所有监听 | removeAllListeners 方法 | ✅ 完全支持 |
2.4 技术架构图
2.5 典型应用场景
| 场景 | 描述 | 示例 |
|---|---|---|
| 摇一摇抽奖 | 摇动触发抽奖活动 | 🎰 营销活动、福利发放 |
| 摇一摇换题 | 摇动切换题目或内容 | 📝 题库应用、随机推荐 |
| 摇一摇反馈 | 摇动触发反馈入口 | 💬 用户反馈、问题报告 |
| 摇一摇刷新 | 摇动刷新页面内容 | 🔄 内容刷新、数据更新 |
| 摇一摇彩蛋 | 隐藏功能触发 | 🥚 彩蛋功能、隐藏菜单 |
⚡ 三、快速开始
3.1 环境要求
| 依赖项 | 版本要求 |
|---|---|
| React Native | 0.72.x / 0.77.x |
| RNOH (鸿蒙框架) | 0.72.90 / 0.77.18 |
| HarmonyOS SDK | 6.0.0.47+ (API 20) |
| DevEco Studio | 5.0.3+ / 6.0+ |
| Node.js | 16.18.0+ / 18.x |
3.2 一键安装
创建鸿蒙项目的过程不再进行描述,不懂得看这篇:https://blog.csdn.net/u011178696/article/details/151932277
npm install @react-native-ohos/react-native-shake@5.6.3-rc.1
或使用 yarn:
yarn add @react-native-ohos/react-native-shake@5.6.3-rc.1
3.3 验证安装
安装完成后,检查 package.json 文件:
{
"dependencies": {
"@react-native-ohos/react-native-shake": "^5.6.3-rc.1"
}
}
🔧 四、HarmonyOS 平台配置
4.1 权限配置

⚠️ 此库需要加速度计权限,必须在
module.json5中配置。
打开 entry/src/main/module.json5,添加权限:
"requestPermissions": [
{
"name": "ohos.permission.ACCELEROMETER"
}
]
4.2 AutoLink 配置(推荐)
🎉 5.6.3 版本支持 AutoLink,可自动完成原生端配置!
如果你的项目已接入 AutoLink,安装依赖后会自动完成原生端配置,无需手动操作。
Autolink 框架指导文档:https://gitcode.com/openharmony-sig/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md
4.3 ManualLink 配置(手动配置)
⚠️ 如果你使用的是 6.0.2 或更高版本,需要手动配置原生端代码。
步骤 1:配置 oh-package.json5
在项目根目录的 oh-package.json5 文件中添加(根据自己的版本来,不一定是我这个版本):
{
"overrides": {
"@rnoh/react-native-openharmony": "0.72.90"
}
}
步骤 2:引入 HAR 包
在 entry/oh-package.json5 文件中添加依赖:
"dependencies": {
"@rnoh/react-native-openharmony": "0.72.90",
"@react-native-ohos/react-native-shake": "file:../../node_modules/@react-native-ohos/react-native-shake/harmony/shake_package.har"
}
步骤 3:配置 CMakeLists.txt
在 entry/src/main/cpp/CMakeLists.txt 文件中添加:
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-shake/src/main/cpp" ./shake_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_shake)
步骤 4:配置 PackageProvider.cpp
在 entry/src/main/cpp/PackageProvider.cpp 文件中添加:
+ #include "ShakePackage.h"
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
+ std::make_shared<ShakePackage>(ctx)
};
}
步骤 5:引入 ShakePackage
在 entry/src/main/ets/RNPackagesFactory.ts 文件中添加:
+ import { ShakePackage } from "@react-native-ohos/react-native-shake/ts";
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
+ new ShakePackage(ctx)
];
}
📱 五、基础使用
5.1 添加摇一摇监听
最基础的使用方式:
import RNShake from 'react-native-shake';
useEffect(() => {
const subscription = RNShake.addListener(() => {
console.log('检测到摇一摇!');
});
return () => {
subscription.remove();
};
}, []);
5.2 完整示例
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import RNShake from 'react-native-shake';
export default function App() {
const [shakeCount, setShakeCount] = useState(0);
useEffect(() => {
const subscription = RNShake.addListener(() => {
setShakeCount((prev) => prev + 1);
});
return () => {
subscription.remove();
};
}, []);
return (
<View style={styles.container}>
<Text style={styles.title}>摇一摇计数器</Text>
<Text style={styles.count}>{shakeCount}</Text>
<Text style={styles.hint}>摇晃手机试试!</Text>
</View>
);
}
🎨 六、进阶用法
6.1 摇一摇触发动画
结合动画效果增强用户体验:
import { Animated } from 'react-native';
const [scale] = useState(new Animated.Value(1));
useEffect(() => {
const subscription = RNShake.addListener(() => {
Animated.sequence([
Animated.timing(scale, {
toValue: 1.2,
duration: 100,
useNativeDriver: true,
}),
Animated.timing(scale, {
toValue: 1,
duration: 100,
useNativeDriver: true,
}),
]).start();
});
return () => subscription.remove();
}, []);
6.2 摇一摇触发随机内容
const items = ['🍎', '🍊', '🍋', '🍇', '🍓', '🍑'];
const [currentItem, setCurrentItem] = useState('🍎');
useEffect(() => {
const subscription = RNShake.addListener(() => {
const randomIndex = Math.floor(Math.random() * items.length);
setCurrentItem(items[randomIndex]);
});
return () => subscription.remove();
}, []);
6.3 移除所有监听
RNShake.removeAllListeners();
📚 七、API 详解
7.1 RNShake 方法
addListener
添加摇一摇事件监听器,返回一个订阅对象。
const subscription = RNShake.addListener(() => {
console.log('摇一摇触发!');
});
subscription.remove();
removeAllListeners
移除所有摇一摇事件监听器。
RNShake.removeAllListeners();
⚠️ 八、注意事项与常见问题
8.1 权限要求
| 权限名称 | 说明 |
|---|---|
| ohos.permission.ACCELEROMETER | 加速度计权限 |
8.2 常见问题
Q1: 摇一摇不触发?
A: 检查是否已配置 ohos.permission.ACCELEROMETER 权限。
Q2: 如何调整灵敏度?
A: 当前版本使用默认灵敏度,暂不支持自定义灵敏度配置。
Q3: 监听器没有正确移除?
A: 确保在 useEffect 的清理函数中调用 subscription.remove()。
Q4: 摇晃时弹出 React Native Dev Menu?
A: 这是 React Native 开发模式的默认行为。在开发环境中,摇晃设备会触发开发者菜单。有以下解决方案:
-
生产环境自动禁用:在 release 构建中,开发者菜单会自动禁用,不会影响用户体验。
-
开发环境临时禁用:如果需要在开发环境测试摇一摇功能,可以在
Index.ets中修改rnInstanceConfig配置,设置devMenuEnabled: false。 -
调整摇晃灵敏度:可以适当降低
react-native-shake的触发频率,避免与系统开发者菜单冲突。
💻 九、完整示例代码
精美摇一摇示例

import React, { useState, useEffect, useRef } from 'react';
import {
View,
Text,
StyleSheet,
SafeAreaView,
Animated,
TouchableOpacity,
} from 'react-native';
import RNShake from 'react-native-shake';
const emojis = ['🎲', '🎰', '🎯', '🎪', '🎨', '🎭'];
const messages = [
'运气不错!',
'再来一次!',
'好运连连!',
'惊喜不断!',
];
export default function App() {
const [shakeCount, setShakeCount] = useState(0);
const [currentEmoji, setCurrentEmoji] = useState('🎲');
const [message, setMessage] = useState('摇晃手机试试');
const [isShaking, setIsShaking] = useState(false);
const scaleAnim = useRef(new Animated.Value(1)).current;
const rotateAnim = useRef(new Animated.Value(0)).current;
useEffect(() => {
const subscription = RNShake.addListener(() => {
handleShake();
});
return () => {
subscription.remove();
};
}, []);
const handleShake = () => {
if (isShaking) return;
setIsShaking(true);
setShakeCount((prev) => prev + 1);
const randomEmoji = emojis[Math.floor(Math.random() * emojis.length)];
const randomMessage = messages[Math.floor(Math.random() * messages.length)];
setCurrentEmoji(randomEmoji);
setMessage(randomMessage);
Animated.sequence([
Animated.parallel([
Animated.timing(scaleAnim, {
toValue: 1.3,
duration: 150,
useNativeDriver: true,
}),
Animated.timing(rotateAnim, {
toValue: 1,
duration: 150,
useNativeDriver: true,
}),
]),
Animated.parallel([
Animated.timing(scaleAnim, {
toValue: 1,
duration: 150,
useNativeDriver: true,
}),
Animated.timing(rotateAnim, {
toValue: 0,
duration: 150,
useNativeDriver: true,
}),
]),
]).start(() => {
setIsShaking(false);
});
};
const resetCount = () => {
setShakeCount(0);
setCurrentEmoji('🎲');
setMessage('摇晃手机试试');
};
const spin = rotateAnim.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg'],
});
return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
<Text style={styles.title}>摇一摇</Text>
</View>
<View style={styles.content}>
<Animated.View
style={[
styles.emojiContainer,
{
transform: [{ scale: scaleAnim }, { rotate: spin }],
},
]}
>
<Text style={styles.emoji}>{currentEmoji}</Text>
</Animated.View>
<Text style={styles.message}>{message}</Text>
<View style={styles.statsContainer}>
<View style={styles.statItem}>
<Text style={styles.statValue}>{shakeCount}</Text>
<Text style={styles.statLabel}>摇动次数</Text>
</View>
</View>
</View>
<View style={styles.footer}>
<TouchableOpacity style={styles.resetButton} onPress={resetCount}>
<Text style={styles.resetButtonText}>重置计数</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#1a1a2e',
},
header: {
padding: 20,
backgroundColor: '#16213e',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#fff',
textAlign: 'center',
},
content: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: 20,
},
emojiContainer: {
width: 140,
height: 140,
borderRadius: 70,
backgroundColor: '#16213e',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 30,
borderWidth: 3,
borderColor: '#00d4ff',
shadowColor: '#00d4ff',
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0.5,
shadowRadius: 20,
elevation: 10,
},
emoji: {
fontSize: 64,
},
message: {
fontSize: 22,
fontWeight: '600',
color: '#00d4ff',
marginBottom: 40,
},
statsContainer: {
flexDirection: 'row',
},
statItem: {
alignItems: 'center',
backgroundColor: '#16213e',
paddingHorizontal: 40,
paddingVertical: 20,
borderRadius: 20,
},
statValue: {
fontSize: 40,
fontWeight: 'bold',
color: '#fff',
},
statLabel: {
fontSize: 14,
color: '#888',
marginTop: 5,
},
footer: {
padding: 20,
},
resetButton: {
backgroundColor: '#00d4ff',
paddingVertical: 14,
borderRadius: 12,
alignItems: 'center',
},
resetButtonText: {
fontSize: 16,
color: '#1a1a2e',
fontWeight: '600',
},
});
🔗 十、相关资源
📝 十一、总结
本文详细介绍了 react-native-shake 在 HarmonyOS 平台的使用方法。通过 Shake 组件,你可以轻松实现摇一摇交互功能。
核心要点:
- ✅ 简单易用的 API 设计
- ✅ 基于订阅模式的事件监听
- ✅ 需要配置加速度计权限
- ✅ 记得在组件卸载时移除监听
希望本文能帮助你在 HarmonyOS 项目中顺利集成摇一摇功能!
更多推荐


所有评论(0)