昇思25天学习打卡营第1天|wo132, 开心快乐的学习
本文介绍了在React Native中开发鸿蒙(HarmonyOS)组件的方法,主要包括:1)鸿蒙开发基础,需掌握DevEco Studio、HarmonyOS SDK等工具;2)React Native集成方案,如使用WebView加载鸿蒙应用、通过Native Modules桥接原生代码、利用Deep Linking传递数据;3)职业发展建议,强调持续学习和实践优化。同时提供了"植物
在React Native中开发鸿组件(这里指的是鸿蒙(HarmonyOS)组件),你需要了解鸿蒙开发的基础以及如何在React Native项目中集成鸿蒙应用。鸿蒙OS是由华为开发的一个分布式操作系统,主要用于其智能设备,如手机、平板、智能手表等。
- 了解鸿蒙开发基础
首先,你需要熟悉鸿蒙OS的开发环境设置和基本开发流程。这包括:
- 开发工具:使用DevEco Studio作为开发IDE。
- SDK:下载并安装HarmonyOS SDK。
- 语言与框架:主要使用Java/Kotlin进行应用开发,但也可以通过C/C++扩展功能。
- 在React Native中集成鸿蒙应用
React Native本身主要用于Harmony和Harmony平台的开发,但你可以通过以下几种方式将鸿蒙应用集成到React Native项目中:
A. 使用WebView
一种简单的方法是使用WebView来加载鸿蒙应用的网页版或通过一个WebView桥接本地代码与鸿蒙应用。
-
在React Native中添加WebView:
npm install react-native-webview -
使用WebView加载鸿蒙应用的URL:
import React from 'react'; import { WebView } from 'react-native-webview'; const HarmonyApp = () => { return ( <WebView source={{ uri: 'https://your-harmony-app-url.com' }} style={{ flex: 1 }} /> ); }; export default HarmonyApp;
B. 使用Native Modules
创建一个Native Module来桥接React Native和鸿蒙原生应用。
-
在DevEco Studio中创建一个鸿蒙应用。
-
开发Native Module:创建一个Java/Kotlin模块,在其中实现与鸿蒙应用交互的逻辑。
-
在React Native中调用Native Module:使用
react-native-bridge或其他桥接库来调用鸿蒙原生模块。例如,使用
react-native-bridge:npm install react-native-bridge然后在JavaScript中调用:
import { NativeModules } from 'react-native'; const { HarmonyModule } = NativeModules;
C. 使用Deep Linking或Intent传递数据
如果你的鸿蒙应用支持Deep Linking或Intent传递数据,你可以在React Native中处理这些链接或Intent,并据此与鸿蒙应用交互。
- 职业发展规划和开发代码详情
对于职业发展规划,你可以考虑以下步骤:
- 学习鸿蒙开发:深入学习鸿蒙OS的APIs和开发工具。
- 实践项目:在项目中实践鸿蒙应用的开发与集成。
- 优化集成方案:不断优化React Native与鸿蒙应用的集成方案,提高用户体验和性能。
- 持续学习:关注鸿蒙OS的最新动态和更新,持续学习新技术和新特性。
- 分享和交流:参与开源项目,分享你的经验,与其他开发者交流。
通过这些步骤,你可以有效地在React Native项目中开发并集成鸿蒙组件,同时规划你的职业发展路径。
开发一个名为“植物养护智能助手”的React Native应用,涉及到多个技术层面,包括前端UI设计、后端数据处理以及可能的硬件接口(例如传感器数据采集)。下面,我将提供一个基本的开发指南和代码示例,帮助你开始这个项目。
- 环境准备
首先,确保你的开发环境已经安装了Node.js和React Native。你可以通过以下步骤安装React Native环境:
安装Node.js (如果尚未安装)
安装React Native CLI
npm install -g react-native-cli
创建一个新的React Native项目
react-native init PlantCareAssistant
进入项目目录
cd PlantCareAssistant
- 安装依赖
为了简化开发,可以使用一些现成的库来帮助处理植物养护相关的功能,例如使用react-native-vector-icons来添加图标、react-native-camera来处理图像识别等。
安装图标库
npm install react-native-vector-icons
安装相机库(可选,根据需求)
npm install react-native-camera
- 项目结构规划
创建一个基本的项目结构,例如:
PlantCareAssistant/
|-- Harmony/
|-- Harmony/
|-- src/
|-- components/
|-- screens/
|-- HomeScreen.js
|-- CareTipsScreen.js
|-- App.js
|-- package.json
- 开发界面组件
HomeScreen.js
import React from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome'; // 假设使用FontAwesome图标库
const HomeScreen = ({ navigation }) => {
return (
<View style={styles.container}>
<Text style={styles.title}>植物养护智能助手</Text>
<Button title="查看养护建议" onPress={() => navigation.navigate('CareTips')} />
<Icon name="leaf" size={50} color="green" /> {/* 显示一个叶子图标 */}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 24,
marginBottom: 20,
},
});
export default HomeScreen;
CareTipsScreen.js
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome'; // 使用相同图标库
const CareTipsScreen = () => {
return (
<View style={styles.container}>
<Text style={styles.title}>养护建议</Text>
<Text>请每天给植物浇水。</Text> {/* 示例文本 */}
<Icon name="info-circle" size={30} color="blue" /> {/* 信息图标 */}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 24,
marginBottom: 20,
},
});
export default CareTipsScreen;
- 导航设置(使用React Navigation)
安装React Navigation:
npm install @react-navigation/native @react-navigation/stack react-native-screens react-native-safe-area-context @react-navigation/native-stack @react-navigation/stack @react-navigation/bottom-tabs @react-navigation/material-top-tabs @react-navigation/material-bottom-tabs @react-navigation/drawer @react-navigation/elements @react-navigation/routers @react-navigation/web react-native-tab-view react-native-pager-view react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context react-native-svg expo @expo/vector-icons expo-linear-gradient expo-constants expo-linking --save` 确保所有依赖都正确安装。`npm install`。`npx pod-install
真实演示案例代码:
// app.tsx
import React, { useState } from 'react';
import { SafeAreaView, View, Text, StyleSheet, TouchableOpacity, ScrollView, Dimensions, Alert, FlatList } from 'react-native';
// 图标库
const ICONS = {
sun: '🌅',
moon: '🌙',
heart: '❤️',
message: '💬',
like: '👍',
share: '🔄',
user: '👤',
stats: '📊',
};
const { width } = Dimensions.get('window');
// 早安问候类型
type GoodMorning = {
id: string;
sender: string;
receiver: string;
message: string;
timestamp: string;
likes: number;
isLiked: boolean;
isSent: boolean;
mood: 'happy' | 'excited' | 'calm' | 'energetic';
};
// 好友类型
type Friend = {
id: string;
name: string;
avatar: string;
lastActive: string;
isOnline: boolean;
};
// 统计类型
type StatsItem = {
title: string;
value: string | number;
icon: string;
color: string;
};
// 早安问候卡片组件
const GoodMorningCard = ({
greeting,
onLike,
onShare
}: {
greeting: GoodMorning;
onLike: (id: string) => void;
onShare: (id: string) => void;
}) => {
const getMoodEmoji = () => {
switch (greeting.mood) {
case 'happy': return '😊';
case 'excited': return '🤩';
case 'calm': return '😌';
case 'energetic': return '💪';
default: return '😊';
}
};
return (
<View style={styles.greetingCard}>
<View style={styles.greetingHeader}>
<View style={styles.senderInfo}>
<Text style={styles.senderAvatar}>{ICONS.user}</Text>
<View>
<Text style={styles.senderName}>{greeting.sender}</Text>
<Text style={styles.receiverInfo}>发送给 {greeting.receiver}</Text>
</View>
</View>
<Text style={styles.timestamp}>{greeting.timestamp}</Text>
</View>
<View style={styles.greetingContent}>
<Text style={styles.moodEmoji}>{getMoodEmoji()}</Text>
<Text style={styles.greetingText}>{greeting.message}</Text>
</View>
<View style={styles.greetingFooter}>
<TouchableOpacity style={styles.actionButton} onPress={() => onLike(greeting.id)}>
<Text style={[styles.actionIcon, greeting.isLiked && styles.likedIcon]}>{ICONS.like}</Text>
<Text style={styles.actionText}>{greeting.likes}</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.actionButton} onPress={() => onShare(greeting.id)}>
<Text style={styles.actionIcon}>{ICONS.share}</Text>
<Text style={styles.actionText}>分享</Text>
</TouchableOpacity>
</View>
</View>
);
};
// 好友卡片组件
const FriendCard = ({
friend,
onSelect
}: {
friend: Friend;
onSelect: (friend: Friend) => void
}) => {
return (
<TouchableOpacity style={styles.friendCard} onPress={() => onSelect(friend)}>
<View style={[styles.friendAvatar, friend.isOnline && styles.onlineStatus]}>
<Text style={styles.avatarText}>{ICONS.user}</Text>
</View>
<View style={styles.friendInfo}>
<Text style={styles.friendName}>{friend.name}</Text>
<Text style={styles.lastActive}>上次活跃: {friend.lastActive}</Text>
</View>
</TouchableOpacity>
);
};
// 统计卡片组件
const StatsCard = ({
title,
value,
icon,
color
}: {
title: string;
value: string | number;
icon: string;
color: string
}) => {
return (
<View style={styles.statCard}>
<View style={[styles.statIcon, { backgroundColor: `${color}20` }]}>
<Text style={[styles.statIconText, { color }]}>{icon}</Text>
</View>
<View style={styles.statInfo}>
<Text style={styles.statValue}>{value}</Text>
<Text style={styles.statTitle}>{title}</Text>
</View>
</View>
);
};
// 主页面组件
const GoodMorningApp: React.FC = () => {
const [friends, setFriends] = useState<Friend[]>([
{ id: '1', name: '张小明', avatar: '', lastActive: '刚刚', isOnline: true },
{ id: '2', name: '李小红', avatar: '', lastActive: '5分钟前', isOnline: true },
{ id: '3', name: '王大伟', avatar: '', lastActive: '2小时前', isOnline: false },
{ id: '4', name: '陈美丽', avatar: '', lastActive: '1天前', isOnline: true },
{ id: '5', name: '刘小华', avatar: '', lastActive: '3天前', isOnline: false },
]);
const [greetings, setGreetings] = useState<GoodMorning[]>([
{
id: '1',
sender: '张小明',
receiver: '我',
message: '新的一天开始了,愿你拥有美好的一天!',
timestamp: '06:30',
likes: 12,
isLiked: false,
isSent: true,
mood: 'happy'
},
{
id: '2',
sender: '我',
receiver: '李小红',
message: '早安!今天也要元气满满哦!',
timestamp: '07:15',
likes: 8,
isLiked: true,
isSent: true,
mood: 'energetic'
},
{
id: '3',
sender: '王大伟',
receiver: '我',
message: '早上好!今天天气不错,适合出门走走。',
timestamp: '08:00',
likes: 5,
isLiked: false,
isSent: false,
mood: 'calm'
},
{
id: '4',
sender: '我',
receiver: '陈美丽',
message: '美好的早晨,愿你的心情也如阳光般灿烂!',
timestamp: '06:45',
likes: 15,
isLiked: true,
isSent: true,
mood: 'excited'
}
]);
const [stats] = useState<StatsItem[]>([
{ title: '发送问候', value: 12, icon: ICONS.sun, color: '#f59e0b' },
{ title: '收到问候', value: 8, icon: ICONS.moon, color: '#6366f1' },
{ title: '好友总数', value: 24, icon: ICONS.user, color: '#10b981' },
{ title: '互动次数', value: 36, icon: ICONS.message, color: '#3b82f6' },
]);
const [selectedFriend, setSelectedFriend] = useState<Friend | null>(null);
const handleLike = (id: string) => {
setGreetings(prev =>
prev.map(greeting =>
greeting.id === id
? { ...greeting, likes: greeting.isLiked ? greeting.likes - 1 : greeting.likes + 1, isLiked: !greeting.isLiked }
: greeting
)
);
};
const handleShare = (id: string) => {
Alert.alert('分享', `分享这条早安问候到其他平台`);
};
const handleSelectFriend = (friend: Friend) => {
setSelectedFriend(friend);
Alert.alert('选择好友', `选择给 ${friend.name} 发送早安问候`);
};
const sendGoodMorning = () => {
if (!selectedFriend) {
Alert.alert('提示', '请选择要发送问候的好友');
return;
}
const newGreeting: GoodMorning = {
id: Date.now().toString(),
sender: '我',
receiver: selectedFriend.name,
message: '早安!愿你今天充满能量!',
timestamp: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
likes: 0,
isLiked: false,
isSent: true,
mood: 'happy'
};
setGreetings([newGreeting, ...greetings]);
setSelectedFriend(null);
Alert.alert('发送成功', `已向 ${selectedFriend.name} 发送早安问候`);
};
return (
<SafeAreaView style={styles.container}>
{/* 头部 */}
<View style={styles.header}>
<Text style={styles.title}>早安问候</Text>
<TouchableOpacity style={styles.statsButton}>
<Text style={styles.statsText}>{ICONS.stats} 统计</Text>
</TouchableOpacity>
</View>
{/* 统计卡片 */}
<ScrollView style={styles.content}>
<View style={styles.statsContainer}>
{stats.map((stat, index) => (
<StatsCard
key={index}
title={stat.title}
value={stat.value}
icon={stat.icon}
color={stat.color}
/>
))}
</View>
{/* 好友列表 */}
<Text style={styles.sectionTitle}>好友列表</Text>
<FlatList
data={friends}
keyExtractor={item => item.id}
renderItem={({ item }) => (
<FriendCard
friend={item}
onSelect={handleSelectFriend}
/>
)}
horizontal
showsHorizontalScrollIndicator={false}
style={styles.friendsList}
/>
{/* 发送问候按钮 */}
<TouchableOpacity style={styles.sendButton} onPress={sendGoodMorning}>
<Text style={styles.sendButtonText}>发送早安问候 {ICONS.sun}</Text>
</TouchableOpacity>
{/* 问候记录标题 */}
<View style={styles.sectionHeader}>
<Text style={styles.sectionTitle}>问候记录</Text>
<Text style={styles.recordCount}>({greetings.length} 条记录)</Text>
</View>
{/* 问候列表 */}
<FlatList
data={greetings}
keyExtractor={item => item.id}
renderItem={({ item }) => (
<GoodMorningCard
greeting={item}
onLike={handleLike}
onShare={handleShare}
/>
)}
showsVerticalScrollIndicator={false}
/>
{/* 活跃度趋势 */}
<View style={styles.trendContainer}>
<Text style={styles.trendTitle}>活跃度趋势</Text>
<View style={styles.trendChart}>
{[70, 85, 60, 90, 75, 95, 80].map((value, index) => (
<View key={index} style={styles.trendItem}>
<View style={styles.trendBar}>
<View
style={[
styles.trendFill,
{
height: `${value}%`,
backgroundColor: value > 80 ? '#10b981' : value > 60 ? '#f59e0b' : '#ef4444'
}
]}
/>
</View>
<Text style={styles.trendLabel}>{['周一', '周二', '周三', '周四', '周五', '周六', '周日'][index]}</Text>
</View>
))}
</View>
</View>
{/* 使用说明 */}
<View style={styles.instructionCard}>
<Text style={styles.instructionTitle}>使用说明</Text>
<Text style={styles.instructionText}>• 点击好友头像可选择发送早安问候</Text>
<Text style={styles.instructionText}>• 点击心形图标可点赞收到的问候</Text>
<Text style={styles.instructionText}>• 点击分享按钮可转发问候内容</Text>
<Text style={styles.instructionText}>• 每天发送早安问候增进友谊</Text>
</View>
</ScrollView>
{/* 底部导航 */}
<View style={styles.bottomNav}>
<TouchableOpacity style={styles.navItem}>
<Text style={styles.navIcon}>{ICONS.sun}</Text>
<Text style={styles.navText}>早安</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem}>
<Text style={styles.navIcon}>{ICONS.user}</Text>
<Text style={styles.navText}>好友</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.navItem, styles.activeNavItem]}>
<Text style={styles.navIcon}>{ICONS.message}</Text>
<Text style={styles.navText}>记录</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem}>
<Text style={styles.navIcon}>{ICONS.heart}</Text>
<Text style={styles.navText}>喜好</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f8fafc',
},
header: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
padding: 20,
backgroundColor: '#ffffff',
borderBottomWidth: 1,
borderBottomColor: '#e2e8f0',
},
title: {
fontSize: 20,
fontWeight: 'bold',
color: '#1e293b',
},
statsButton: {
backgroundColor: '#3b82f6',
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 20,
},
statsText: {
color: '#ffffff',
fontSize: 14,
fontWeight: '500',
},
content: {
flex: 1,
padding: 16,
},
statsContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
marginBottom: 16,
},
statCard: {
backgroundColor: '#ffffff',
borderRadius: 12,
padding: 16,
width: (width - 48) / 2,
marginBottom: 12,
elevation: 1,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
flexDirection: 'row',
alignItems: 'center',
},
statIcon: {
width: 36,
height: 36,
borderRadius: 18,
alignItems: 'center',
justifyContent: 'center',
marginRight: 12,
},
statIconText: {
fontSize: 18,
},
statInfo: {
flex: 1,
},
statValue: {
fontSize: 20,
fontWeight: 'bold',
color: '#1e293b',
},
statTitle: {
fontSize: 12,
color: '#64748b',
marginTop: 4,
},
sectionTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#1e293b',
marginVertical: 12,
},
friendsList: {
marginBottom: 16,
},
friendCard: {
backgroundColor: '#ffffff',
borderRadius: 12,
padding: 16,
marginRight: 12,
alignItems: 'center',
width: 80,
elevation: 1,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
},
friendAvatar: {
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#dbeafe',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 8,
position: 'relative',
},
onlineStatus: {
borderWidth: 2,
borderColor: '#10b981',
},
avatarText: {
fontSize: 20,
color: '#3b82f6',
},
friendName: {
fontSize: 12,
fontWeight: 'bold',
color: '#1e293b',
textAlign: 'center',
},
lastActive: {
fontSize: 10,
color: '#64748b',
textAlign: 'center',
marginTop: 4,
},
friendInfo: {
alignItems: 'center',
},
sendButton: {
backgroundColor: '#f59e0b',
paddingVertical: 12,
borderRadius: 8,
alignItems: 'center',
marginBottom: 16,
},
sendButtonText: {
color: '#ffffff',
fontSize: 16,
fontWeight: '500',
},
sectionHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 12,
},
recordCount: {
fontSize: 14,
color: '#64748b',
},
greetingCard: {
backgroundColor: '#ffffff',
borderRadius: 12,
padding: 16,
marginBottom: 12,
elevation: 1,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
},
greetingHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 12,
},
senderInfo: {
flexDirection: 'row',
alignItems: 'center',
},
senderAvatar: {
width: 32,
height: 32,
borderRadius: 16,
backgroundColor: '#dbeafe',
alignItems: 'center',
justifyContent: 'center',
marginRight: 12,
},
senderName: {
fontSize: 14,
fontWeight: 'bold',
color: '#1e293b',
},
receiverInfo: {
fontSize: 12,
color: '#64748b',
},
timestamp: {
fontSize: 12,
color: '#94a3b8',
},
greetingContent: {
flexDirection: 'row',
alignItems: 'flex-start',
marginBottom: 12,
},
moodEmoji: {
fontSize: 20,
marginRight: 8,
marginTop: 2,
},
greetingText: {
fontSize: 14,
color: '#334155',
lineHeight: 20,
flex: 1,
},
greetingFooter: {
flexDirection: 'row',
justifyContent: 'flex-start',
},
actionButton: {
flexDirection: 'row',
alignItems: 'center',
marginRight: 20,
},
actionIcon: {
fontSize: 16,
color: '#64748b',
marginRight: 4,
},
likedIcon: {
color: '#ef4444',
},
actionText: {
fontSize: 12,
color: '#64748b',
},
trendContainer: {
backgroundColor: '#ffffff',
borderRadius: 12,
padding: 16,
marginTop: 16,
elevation: 1,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
},
trendTitle: {
fontSize: 16,
fontWeight: 'bold',
color: '#1e293b',
marginBottom: 12,
},
trendChart: {
flexDirection: 'row',
justifyContent: 'space-around',
},
trendItem: {
alignItems: 'center',
flex: 1,
},
trendBar: {
width: 20,
height: 80,
backgroundColor: '#e2e8f0',
borderRadius: 4,
justifyContent: 'flex-end',
alignItems: 'center',
marginBottom: 8,
},
trendFill: {
width: '100%',
borderRadius: 4,
},
trendLabel: {
fontSize: 10,
color: '#64748b',
},
instructionCard: {
backgroundColor: '#ffffff',
borderRadius: 12,
padding: 16,
marginTop: 16,
elevation: 1,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
},
instructionTitle: {
fontSize: 16,
fontWeight: 'bold',
color: '#1e293b',
marginBottom: 8,
},
instructionText: {
fontSize: 12,
color: '#64748b',
lineHeight: 18,
marginBottom: 4,
},
bottomNav: {
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: '#ffffff',
borderTopWidth: 1,
borderTopColor: '#e2e8f0',
paddingVertical: 12,
},
navItem: {
alignItems: 'center',
flex: 1,
},
activeNavItem: {
paddingBottom: 2,
borderBottomWidth: 2,
borderBottomColor: '#3b82f6',
},
navIcon: {
fontSize: 20,
color: '#94a3b8',
marginBottom: 4,
},
activeNavIcon: {
color: '#3b82f6',
},
navText: {
fontSize: 12,
color: '#94a3b8',
},
activeNavText: {
color: '#3b82f6',
fontWeight: '500',
},
});
export default GoodMorningApp;

打包
接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

打包之后再将打包后的鸿蒙OpenHarmony文件拷贝到鸿蒙的DevEco-Studio工程目录去:


最后运行效果图如下显示:
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。



所有评论(0)