React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
本文介绍了一个基于React Native的狗狗领养中心应用开发实践。该应用采用组件化架构设计,核心功能包括: 数据结构:使用结构化数据存储狗狗信息,包含基本属性、图片和状态标记 组件设计:通过可复用的DogCard组件展示单个狗狗信息,AdoptionList管理整体列表 状态管理:利用useState实现收藏状态切换和领养申请交互 界面布局:采用卡片式设计,结合图片和文字信息展示 跨平台适配:
这个狗狗领养中心应用采用了现代 React Native 组件化架构,通过清晰的职责分离实现了代码的模块化和可维护性。核心组件 DogCard 作为独立的可复用单元,负责单个狗狗信息的展示和交互,而 AdoptionList 作为主容器,负责状态管理和狗狗列表的渲染。
数据结构
const DOGS_DATA = [
{
id: 1,
name: '金毛旺财',
breed: '金毛寻回犬',
age: '2岁',
gender: '公',
size: '大型',
location: '北京市朝阳区',
description: '性格温顺,喜欢与人亲近,适合家庭饲养。',
image: 'https://picsum.photos/300/200?random=1',
isFavorite: false,
tags: ['友善', '活泼', '聪明']
},
// 更多狗狗数据...
];
数据结构设计全面,包含了狗狗的基本信息、外观特征、性格特点和领养状态等。使用 isFavorite 字段标记收藏状态,tags 数组存储狗狗的性格标签,这种结构化的数据设计为后续的功能扩展和数据管理提供了便利。
可复用 DogCard 组件
const DogCard: React.FC<{
dog: any,
onToggleFavorite: (id: number) => void,
onAdopt: (id: number) => void
}> = ({ dog, onToggleFavorite, onAdopt }) => {
// 组件实现...
};
DogCard 组件设计为高度可配置的通用组件,通过 props 接收狗狗数据和回调函数。这种设计使得组件可以在不同场景中灵活使用,只需传入不同的参数即可实现不同的功能。组件内部包含了图片、基本信息、属性标签和操作按钮等完整的展示内容。
状态管理
const [dogs, setDogs] = useState(DOGS_DATA);
const toggleFavorite = (id: number) => {
setDogs(dogs.map(dog =>
dog.id === id ? { ...dog, isFavorite: !dog.isFavorite } : dog
));
};
const handleAdopt = (id: number) => {
alert(`已提交对 ${dogs.find(d => d.id === id)?.name} 的领养申请`);
};
使用 useState Hook 管理狗狗列表状态,初始值为模拟数据 DOGS_DATA。toggleFavorite 函数通过 map 方法更新指定狗狗的收藏状态,实现了状态的响应式更新。handleAdopt 函数通过 alert 显示领养申请提交成功的信息,提供了基本的用户反馈。
交互
<TouchableOpacity onPress={() => onToggleFavorite(dog.id)}>
<Text style={styles.favoriteIcon}>{dog.isFavorite ? '❤️' : '🤍'}</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.adoptionButton} onPress={() => onAdopt(dog.id)}>
<Text style={styles.adoptionButtonText}>申请领养</Text>
</TouchableOpacity>
通过 TouchableOpacity 实现了收藏和领养按钮的点击交互,点击收藏按钮会切换图标状态,点击领养按钮会触发领养申请。这种直观的交互设计提升了用户体验,使得操作流程更加顺畅。
卡片式布局
<View style={styles.dogCard}>
<Image source={{ uri: dog.image }} style={styles.dogImage} />
<View style={styles.dogInfo}>
{/* 狗狗信息 */}
</View>
</View>
狗狗卡片采用了垂直堆叠的布局结构,顶部是狗狗图片,下方是详细信息。这种卡片式布局在移动应用中非常常见,能够清晰地展示信息,同时保持界面的整洁和有序。
响应式
const { width } = Dimensions.get('window');
通过 Dimensions.get('window') 获取屏幕宽度,为后续的响应式布局计算提供基础。虽然在当前实现中没有直接使用这个值进行动态计算,但这种模式为后续的布局调整(如适配不同屏幕尺寸)预留了扩展空间。
-
组件映射:
SafeAreaView→SafeArea或Flex容器ScrollView→List或Scroll组件TouchableOpacity→Button或Text+ 手势事件Image→Image组件View→Flex容器Text→Text组件
-
图片加载适配:
- React Native 中使用
source={{ uri: dog.image }}加载网络图片 - 鸿蒙系统中可以使用
Image组件的src属性,语法类似但可能需要调整
- React Native 中使用
-
样式适配:
- 鸿蒙系统的样式定义方式与 React Native 类似,但属性名称可能略有不同
- 例如,
shadow相关属性在鸿蒙中需要使用elevation或其他等效属性 - 尺寸单位在鸿蒙中默认使用
vp,与 React Native 的密度无关像素概念类似
-
状态管理适配:
- React Native 中使用
useStateHook 管理状态 - 鸿蒙系统中可以使用
@State装饰器实现类似的状态管理 - 对于复杂状态,可以使用鸿蒙的
AppStorage或LocalStorage
- React Native 中使用
-
类型定义优化:
- 当前代码使用
any类型定义dog属性,建议使用 TypeScript 接口明确类型:
interface Dog { id: number; name: string; breed: string; age: string; gender: string; size: string; location: string; description: string; image: string; isFavorite: boolean; tags: string[]; } const DogCard: React.FC<{ dog: Dog; onToggleFavorite: (id: number) => void; onAdopt: (id: number) => void; }> = ({ dog, onToggleFavorite, onAdopt }) => { // 实现... }; - 当前代码使用
-
组件复用优化:
- 考虑使用
React.memo包裹DogCard组件,减少不必要的重渲染:
const DogCard: React.FC<{ dog: Dog; onToggleFavorite: (id: number) => void; onAdopt: (id: number) => void; }> = React.memo(({ dog, onToggleFavorite, onAdopt }) => { // 实现... }); - 考虑使用
-
列表性能优化:
- 对于较长的狗狗列表,建议使用
FlatList替代ScrollView+map的组合,利用虚拟化提升滚动性能:
<FlatList data={dogs} keyExtractor={(item) => item.id.toString()} renderItem={({ item }) => ( <DogCard dog={item} onToggleFavorite={toggleFavorite} onAdopt={handleAdopt} /> )} contentContainerStyle={styles.content} /> - 对于较长的狗狗列表,建议使用
-
图片加载优化:
- 添加图片加载状态和错误处理,提升用户体验:
<Image source={{ uri: dog.image }} style={styles.dogImage} resizeMode="cover" onError={(error) => console.log('Image load error:', error)} /> -
可访问性优化:
- 添加
accessibilityLabel属性,提高应用的可访问性:
<TouchableOpacity style={styles.adoptionButton} onPress={() => onAdopt(dog.id)} accessibilityLabel={`申请领养 ${dog.name}`} > <Text style={styles.adoptionButtonText}>申请领养</Text> </TouchableOpacity> - 添加
这个狗狗领养中心应用展示了 React Native 跨端开发的核心技术要点,通过合理的组件设计、清晰的状态管理和细致的样式管理,实现了一个功能完整、用户体验良好的领养平台。在鸿蒙系统适配方面,通过组件映射、样式适配和布局调整,可以快速实现跨端迁移,保持功能和视觉效果的一致性。
本次解析的代码是一套基于React Native开发的狗狗领养中心实战应用,采用经典的列表+卡片式布局设计,整合了数据渲染、状态管理、组件化拆分、原生样式布局、交互事件处理等核心开发能力,同时实现了收藏切换、领养申请、底部导航等实际业务功能。所有实现均基于React Native原生API与TypeScript基础约束,无第三方UI库依赖,可无缝适配React Native for HarmonyOS鸿蒙桥接方案,实现Android、iOS、鸿蒙多端的原生渲染与交互一致性。本文将从组件化拆分设计、状态驱动的业务逻辑、卡片式布局的跨端适配、样式系统的工程化设计、鸿蒙跨端兼容核心要点等维度,深度解读该实战项目的技术实现思路,剖析React Native在实际业务场景中鸿蒙跨端开发的工程化价值。
一、技术栈
本实战项目延续React Native + TypeScript的核心技术栈,以函数式组件为基础,结合useState实现业务状态管理,通过原生组件实现UI渲染与交互,所有技术选型均围绕鸿蒙跨端兼容、业务实用性、开发工程化、原生体验四大核心原则展开,核心选型与技术特性如下:
- 基础原生组件:选用
SafeAreaView、View、Text、TouchableOpacity、Image、ScrollView等React Native核心原生组件,均为React Native for HarmonyOS已完成深度桥接的基础组件,底层编译为各平台原生组件(鸿蒙Component、Android View、iOS UIView),基于原生渲染引擎执行,规避WebView渲染的性能损耗与布局兼容问题,保证多端原生交互与视觉体验; - 核心能力组件:
Image组件支持远程图片加载(URI方式),完美适配鸿蒙平台的网络图片渲染机制;ScrollView实现长列表的滚动展示,桥接各平台原生滚动控件,适配鸿蒙大屏设备(平板、折叠屏)的内容展示;DimensionsAPI获取设备窗口宽度,为跨端自适应布局提供基础; - React核心能力:
useState实现应用的核心业务状态管理(狗狗收藏状态),遵循React声明式编程与状态驱动渲染核心思想,与鸿蒙ArkUI的@State装饰器状态管理理念高度统一,为跨端业务逻辑一致性提供基础; - 轻量组件化拆分:采用容器组件+展示组件的拆分思路,将页面拆分为
AdoptionList(容器/页面组件,负责数据管理、逻辑处理)与DogCard(展示/原子组件,负责UI渲染、事件透传),实现数据与视图的解耦,符合React组件化开发规范,同时与鸿蒙ArkUI的组件拆分思路一致,便于跨端复用与维护; - 模拟业务数据:通过静态数组模拟狗狗领养业务数据,采用标准化的对象结构,便于后续对接真实接口,同时保证跨端数据渲染的一致性;
- 轻量资源管理:以键值对形式封装
ICONS全局Emoji图标库,选用系统原生支持的Emoji作为视觉元素,避免第三方图标库在鸿蒙平台的桥接兼容问题,减少项目依赖体积,提升多端编译与启动效率; - 原生样式与布局:基于React Native原生的
StyleSheet与Flex布局实现所有UI样式,无第三方UI库依赖,保证跨端布局的精准性、渲染性能与样式兼容性。
本项目的技术选型贴合实际移动端业务开发场景,既满足了狗狗领养中心的核心业务功能需求,又保证了代码的轻量性、可维护性与跨端兼容性,是React Native鸿蒙跨端开发中实际业务应用的典型实践,可快速迁移至电商列表、资讯展示、宠物服务等同类列表卡片式跨端应用。
二、组件化拆分
本项目最核心的工程化设计亮点是基于职责的组件化拆分,将整个应用拆分为AdoptionList页面容器组件与DogCard卡片展示组件,遵循单一职责原则与关注点分离原则——容器组件负责数据管理、业务逻辑处理、事件定义,展示组件负责纯UI渲染、用户交互触发、事件透传,这种拆分方式让代码结构清晰、可维护性强,同时完美适配鸿蒙跨端的工程化开发需求,核心实现要点如下:
1. 组件划分
- AdoptionList(页面/容器组件):作为应用的根组件,承担容器与逻辑中心的职责,包括:初始化模拟业务数据并通过
useState管理;定义核心业务事件(toggleFavorite收藏切换、handleAdopt领养申请);实现搜索筛选栏、页面标题、底部导航等公共UI的渲染;通过循环遍历将狗狗数据传递给DogCard组件,同时绑定事件回调。该组件不关注具体的卡片UI渲染细节,仅负责数据与逻辑的分发,符合容器组件的设计规范; - DogCard(卡片/展示组件):作为纯展示型原子组件,承担UI渲染与交互触发的职责,包括:通过Props接收父组件传递的单个狗狗数据与事件回调;实现卡片的完整UI布局(图片、名称、品种、属性、标签、操作按钮);将用户交互(点击收藏、点击领养、点击分享)透传给父组件的事件回调。该组件无内部状态(纯受控组件),所有数据与行为均由父组件控制,符合展示组件的设计规范。
这种职责划分让两个组件的内聚性极强,耦合性极低,在鸿蒙跨端开发中,若需针对鸿蒙平台定制卡片UI样式,仅需修改DogCard组件;若需修改收藏逻辑,仅需修改AdoptionList组件的toggleFavorite方法,互不影响,大幅提升了跨端开发的维护效率。
2. TypeScript基础约束
DogCard组件通过TypeScript对Props进行了基础的强类型约束,核心定义为:
interface DogCardProps {
dog: any,
onToggleFavorite: (id: number) => void,
onAdopt: (id: number) => void
}
该约束明确了组件的入参类型:dog为任意类型(可后续拓展为具体接口),onToggleFavorite与onAdopt为接收数字类型ID、无返回值的回调函数。这种约束不仅能在开发阶段检测出参数类型与事件传递的错误,还能为跨端团队协作提供清晰的接口文档,同时与鸿蒙ArkUI的Props类型约束思路高度一致,保证了跨端开发的类型一致性。
在事件透传方面,DogCard组件将用户的点击操作(如点击收藏按钮)通过参数传递的方式(onToggleFavorite(dog.id))将狗狗的唯一ID透传给父组件,父组件通过ID精准定位到对应的狗狗数据并处理业务逻辑。这种基于唯一标识的事件透传方式是移动端列表开发的通用规范,无平台专属特性,在鸿蒙、Android、iOS多端的事件处理逻辑完全一致。
3. 跨端状态管理
DogCard组件被设计为纯受控组件,无任何内部状态,所有展示数据(如dog.isFavorite收藏状态、狗狗名称/图片/属性)与行为(收藏、领养)均由父组件AdoptionList通过Props控制。这种设计的核心优势在于:
- 状态单一数据源:整个应用的业务状态(狗狗收藏状态)仅由
AdoptionList的dogs状态管理,避免了多组件状态不一致的问题,保证了跨端渲染的一致性; - 逻辑集中管理:核心业务逻辑集中在
AdoptionList组件,便于后续拓展与修改(如将收藏状态同步到本地存储、云端接口),在鸿蒙跨端开发中,无需在多个组件中修改逻辑,仅需修改核心容器组件即可; - 组件高度复用:
DogCard组件可直接复用到其他需要展示狗狗卡片的跨端页面(如收藏列表、狗狗详情页),仅需传递不同的dog数据与事件回调即可,提升了跨端开发的代码复用率。
在鸿蒙ArkUI开发中,这种纯受控组件的设计思路与@Prop装饰器实现的父子组件状态同步逻辑高度一致,均是通过父组件控制子组件的状态与行为,保证了跨端组件设计思想的统一性。
本项目的核心业务状态是狗狗的收藏状态(isFavorite),基于React的useState钩子实现了该状态的初始化、修改与驱动渲染,同时实现了领养申请的基础业务逻辑,所有状态管理与业务逻辑均遵循React的单向数据流原则,无任何平台专属特性,可在鸿蒙平台无缝兼容,核心实现要点如下:
1. 业务数据的初始化
通过useState初始化狗狗业务数据,核心代码为:
const [dogs, setDogs] = useState(DOGS_DATA);
将模拟的DOGS_DATA数组作为初始值,通过dogs状态存储所有狗狗的完整数据(包括收藏状态、基本信息、图片等),通过setDogs方法修改状态。这种初始化方式与鸿蒙ArkUI的@State dogs: Dog[] = DOGS_DATA状态初始化逻辑高度一致,保证了跨端数据初始渲染的一致性。
同时,模拟数据采用标准化的对象结构,为每个狗狗设置唯一的id标识,这是移动端列表开发的通用规范,不仅便于后续的精准数据操作(如根据ID修改收藏状态),还能保证key属性的唯一性(列表循环时的key={dog.id}),避免React Native的列表渲染警告,提升跨端的渲染性能。
2. 收藏切换逻辑
定义toggleFavorite方法实现狗狗收藏状态的切换,核心代码为:
const toggleFavorite = (id: number) => {
setDogs(dogs.map(dog =>
dog.id === id ? { ...dog, isFavorite: !dog.isFavorite } : dog
));
};
该方法遵循React状态不可变的核心原则,不直接修改原dogs数组与狗狗对象,而是通过以下步骤生成新的状态:
- 通过
map方法遍历原数组,返回一个新的数组; - 通过
id精准匹配到需要修改的狗狗对象; - 通过扩展运算符(…) 复制原狗狗对象的所有属性,避免修改原对象;
- 仅修改
isFavorite属性的取值(取反),实现收藏状态的切换; - 未匹配到的狗狗对象直接返回,保持原有状态。
这种状态修改方式完全基于ES6通用语法,在鸿蒙、Android、iOS的JS引擎中均能正常执行,无跨端兼容问题。当状态更新后,React Native框架会自动触发组件的重渲染,DogCard组件会根据新的isFavorite值更新收藏图标的展示(❤️/🤍),实现状态驱动视图的跨端一致效果。
3. 领养申请逻辑
定义handleAdopt方法实现领养申请的基础业务逻辑,核心代码为:
const handleAdopt = (id: number) => {
alert(`已提交对 ${dogs.find(d => d.id === id)?.name} 的领养申请`);
};
该方法通过id作为唯一标识,通过Array.prototype.find方法精准匹配到对应的狗狗对象,获取狗狗名称后,通过React Native原生的alert方法实现跨端通用的弹窗交互反馈。
alert作为React Native封装的跨平台原生弹窗组件,在鸿蒙平台中会被React Native for HarmonyOS桥接为鸿蒙的原生弹窗(AlertDialog),保证鸿蒙、Android、iOS多端的弹窗样式与交互体验一致性;Array.prototype.find作为ES6通用数组方法,在多端的JS引擎中均能正常执行,保证了数据匹配逻辑的跨端一致性。该方法为基础实现,后续可无缝拓展为对接真实的领养申请接口,无需修改核心逻辑结构。
4. 状态驱动
所有UI的更新均由状态的变化驱动,核心体现为:
- 收藏图标:
DogCard组件根据dog.isFavorite的值渲染不同的图标(❤️为已收藏,🤍为未收藏),当toggleFavorite方法修改isFavorite状态后,图标自动更新; - 狗狗列表:当
dogs状态发生变化时,AdoptionList组件通过map循环遍历的DogCard组件会自动重渲染,保证UI与数据的一致性。
这种状态驱动视图的渲染逻辑,是React的核心设计思想,在鸿蒙ArkUI中通过@State状态与组件属性的绑定实现,二者的设计思路高度统一,保证了跨端开发中UI更新逻辑的一致性,无需为不同平台编写差异化的渲染代码。
真实演示案例代码:
// app.tsx
import React, { useState } from 'react';
import { SafeAreaView, View, Text, StyleSheet, TouchableOpacity, ScrollView, Image, Dimensions } from 'react-native';
// 图标库
const ICONS = {
heart: '❤️',
bookmark: '🔖',
share: '📤',
location: '📍',
calendar: '📅',
gender: '♂♀',
age: '📅',
size: '📏',
info: 'ℹ️',
home: '🏠',
user: '👤',
search: '🔍',
filter: '🔍',
like: '👍',
comment: '💬',
star: '⭐',
paw: '🐾',
dog: '🐕',
cat: '🐈',
plus: '➕',
minus: '➖',
check: '✅',
close: '❌',
edit: '✏️',
delete: '🗑️',
settings: '⚙️',
notification: '🔔',
gift: '🎁',
celebration: '🎉',
smile: '😊',
sad: '😢',
angry: '😠',
surprised: '😲',
thinking: '🤔',
thumbs_up: '👍',
thumbs_down: '👎',
clap: '👏',
wave: '👋',
heart_eyes: '😍',
laughing: '😂',
crying: '😭',
angry_face: '😡',
neutral: '😐',
confused: '😕',
wink: '😉',
tongue: '😛',
sunglasses: '😎',
money_mouth: '🤑',
thinking_face: '🤔',
sleeping: '😴',
dizzy: '😵',
sunglasses_face: '😎',
heart_face: '🥰',
kiss: '😘',
hug: '🤗',
pray: '🙏',
handshake: '🤝',
high_five: '🙌',
peace: '✌️',
ok: '👌',
victory: '✌️',
rock: '🤟',
call_me: '🤙',
point_up: '☝️',
point_down: '👇',
point_left: '👈',
point_right: '👉',
raised_hand: '✋',
raised_fist: '✊',
victory_hand: '✌️',
metal: '🤘',
vulcan: '🖖',
wave_hand: '👋',
clapping_hands: '👏',
open_hands: '👐',
palms_up: '🤲',
handshake_hands: '🤝',
pray_hands: '🙏',
fold_hands: ' folded_hands',
writing_hand: '✍️',
nail_care: '💅',
selfie: '🤳',
flexed_biceps: '💪',
muscle: '💪',
selfie_tone1: ' selfie_tone1',
selfie_tone2: ' selfie_tone2',
selfie_tone3: ' selfie_tone3',
selfie_tone4: ' selfie_tone4',
selfie_tone5: ' selfie_tone5',
selfie_tone6: ' selfie_tone6',
};
const { width } = Dimensions.get('window');
// 模拟狗狗数据
const DOGS_DATA = [
{
id: 1,
name: '金毛旺财',
breed: '金毛寻回犬',
age: '2岁',
gender: '公',
size: '大型',
location: '北京市朝阳区',
description: '性格温顺,喜欢与人亲近,适合家庭饲养。',
image: 'https://picsum.photos/300/200?random=1',
isFavorite: false,
tags: ['友善', '活泼', '聪明']
},
{
id: 2,
name: '柯基小短腿',
breed: '威尔士柯基',
age: '1岁半',
gender: '母',
size: '小型',
location: '上海市浦东新区',
description: '活泼好动,非常聪明,容易训练。',
image: 'https://picsum.photos/300/200?random=2',
isFavorite: true,
tags: ['聪明', '活泼', '可爱']
},
{
id: 3,
name: '哈士奇二哈',
breed: '西伯利亚雪橇犬',
age: '3岁',
gender: '公',
size: '中型',
location: '广州市天河区',
description: '精力充沛,需要大量运动,适合活跃的家庭。',
image: 'https://picsum.photos/300/200?random=3',
isFavorite: false,
tags: ['精力旺盛', '友好', '需要运动']
},
{
id: 4,
name: '泰迪小卷毛',
breed: '贵宾犬',
age: '6个月',
gender: '母',
size: '小型',
location: '深圳市南山区',
description: '非常亲人,毛发卷曲可爱,需要定期美容。',
image: 'https://picsum.photos/300/200?random=4',
isFavorite: false,
tags: ['可爱', '亲人', '需要美容']
},
{
id: 5,
name: '柴犬小王子',
breed: '日本柴犬',
age: '1岁',
gender: '公',
size: '中型',
location: '杭州市西湖区',
description: '独立性强,忠诚,具有典型的狐狸脸特征。',
image: 'https://picsum.photos/300/200?random=5',
isFavorite: true,
tags: ['忠诚', '独立', '可爱']
},
{
id: 6,
name: '边牧小聪明',
breed: '边境牧羊犬',
age: '2岁',
gender: '母',
size: '中型',
location: '成都市锦江区',
description: '智商极高,善于学习,需要大量精神和身体刺激。',
image: 'https://picsum.photos/300/200?random=6',
isFavorite: false,
tags: ['聪明', '需要运动', '活跃']
}
];
const DogCard: React.FC<{
dog: any,
onToggleFavorite: (id: number) => void,
onAdopt: (id: number) => void
}> = ({ dog, onToggleFavorite, onAdopt }) => {
return (
<View style={styles.dogCard}>
<Image source={{ uri: dog.image }} style={styles.dogImage} />
<View style={styles.dogInfo}>
<View style={styles.dogHeader}>
<Text style={styles.dogName}>{dog.name}</Text>
<TouchableOpacity onPress={() => onToggleFavorite(dog.id)}>
<Text style={styles.favoriteIcon}>{dog.isFavorite ? '❤️' : '🤍'}</Text>
</TouchableOpacity>
</View>
<Text style={styles.dogBreed}>{dog.breed}</Text>
<View style={styles.dogAttributes}>
<Text style={styles.attribute}>{ICONS.age} {dog.age}</Text>
<Text style={styles.attribute}>{ICONS.gender} {dog.gender}</Text>
<Text style={styles.attribute}>{ICONS.size} {dog.size}</Text>
</View>
<Text style={styles.location}>{ICONS.location} {dog.location}</Text>
<Text style={styles.description}>{dog.description}</Text>
<View style={styles.tagsContainer}>
{dog.tags.map((tag: string, index: number) => (
<View key={index} style={styles.tag}>
<Text style={styles.tagText}>{tag}</Text>
</View>
))}
</View>
<View style={styles.actionRow}>
<TouchableOpacity style={styles.adoptionButton} onPress={() => onAdopt(dog.id)}>
<Text style={styles.adoptionButtonText}>申请领养</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.shareButton}>
<Text style={styles.shareButtonText}>{ICONS.share} 分享</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
};
const AdoptionList: React.FC = () => {
const [dogs, setDogs] = useState(DOGS_DATA);
const toggleFavorite = (id: number) => {
setDogs(dogs.map(dog =>
dog.id === id ? { ...dog, isFavorite: !dog.isFavorite } : dog
));
};
const handleAdopt = (id: number) => {
alert(`已提交对 ${dogs.find(d => d.id === id)?.name} 的领养申请`);
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
<Text style={styles.title}>狗狗领养中心</Text>
<Text style={styles.subtitle}>寻找您的毛茸茸伙伴</Text>
</View>
<View style={styles.searchFilter}>
<View style={styles.searchContainer}>
<Text style={styles.searchIcon}>{ICONS.search}</Text>
<Text style={styles.searchPlaceholder}>搜索狗狗</Text>
</View>
<TouchableOpacity style={styles.filterButton}>
<Text style={styles.filterText}>{ICONS.filter} 筛选</Text>
</TouchableOpacity>
</View>
<ScrollView contentContainerStyle={styles.content}>
<Text style={styles.sectionTitle}>可领养的狗狗</Text>
<Text style={styles.dogsCount}>{dogs.length} 只狗狗等待新主人</Text>
{dogs.map(dog => (
<DogCard
key={dog.id}
dog={dog}
onToggleFavorite={toggleFavorite}
onAdopt={handleAdopt}
/>
))}
</ScrollView>
<View style={styles.bottomBar}>
<TouchableOpacity style={styles.bottomButton}>
<Text style={styles.bottomButtonText}>{ICONS.home} 首页</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bottomButton}>
<Text style={styles.bottomButtonText}>{ICONS.user} 我的</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bottomButton}>
<Text style={styles.bottomButtonText}>{ICONS.heart} 收藏</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bottomButton}>
<Text style={styles.bottomButtonText}>{ICONS.gift} 领养</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f8f9fa',
},
header: {
paddingTop: 40,
paddingBottom: 20,
paddingHorizontal: 20,
backgroundColor: '#ffffff',
borderBottomWidth: 1,
borderBottomColor: '#e9ecef',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#333',
textAlign: 'center',
},
subtitle: {
fontSize: 16,
color: '#666',
textAlign: 'center',
marginTop: 8,
},
searchFilter: {
flexDirection: 'row',
padding: 16,
backgroundColor: '#ffffff',
borderBottomWidth: 1,
borderBottomColor: '#e9ecef',
},
searchContainer: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#f1f3f5',
borderRadius: 20,
paddingHorizontal: 16,
paddingVertical: 8,
},
searchIcon: {
fontSize: 16,
marginRight: 8,
},
searchPlaceholder: {
color: '#666',
fontSize: 14,
},
filterButton: {
backgroundColor: '#3B82F6',
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 20,
marginLeft: 8,
justifyContent: 'center',
},
filterText: {
color: '#ffffff',
fontSize: 14,
},
content: {
padding: 16,
},
sectionTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#333',
marginBottom: 4,
},
dogsCount: {
fontSize: 14,
color: '#666',
marginBottom: 16,
},
dogCard: {
backgroundColor: '#ffffff',
borderRadius: 12,
marginBottom: 16,
elevation: 3,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
overflow: 'hidden',
},
dogImage: {
width: '100%',
height: 180,
},
dogInfo: {
padding: 16,
},
dogHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 8,
},
dogName: {
fontSize: 18,
fontWeight: 'bold',
color: '#333',
},
favoriteIcon: {
fontSize: 24,
},
dogBreed: {
fontSize: 14,
color: '#666',
marginBottom: 8,
},
dogAttributes: {
flexDirection: 'row',
marginBottom: 8,
},
attribute: {
fontSize: 12,
color: '#475569',
backgroundColor: '#e2e8f0',
paddingHorizontal: 8,
paddingVertical: 4,
borderRadius: 12,
marginRight: 8,
},
location: {
fontSize: 12,
color: '#666',
marginBottom: 8,
},
description: {
fontSize: 14,
color: '#475569',
lineHeight: 20,
marginBottom: 12,
},
tagsContainer: {
flexDirection: 'row',
marginBottom: 12,
},
tag: {
backgroundColor: '#dbeafe',
paddingHorizontal: 8,
paddingVertical: 4,
borderRadius: 12,
marginRight: 6,
},
tagText: {
fontSize: 12,
color: '#3B82F6',
},
actionRow: {
flexDirection: 'row',
justifyContent: 'space-between',
},
adoptionButton: {
backgroundColor: '#3B82F6',
flex: 1,
paddingVertical: 10,
borderRadius: 8,
alignItems: 'center',
marginRight: 8,
},
adoptionButtonText: {
color: '#ffffff',
fontWeight: 'bold',
},
shareButton: {
backgroundColor: '#e2e8f0',
flex: 0.3,
paddingVertical: 10,
borderRadius: 8,
alignItems: 'center',
},
shareButtonText: {
color: '#475569',
fontWeight: 'bold',
},
bottomBar: {
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: '#ffffff',
borderTopWidth: 1,
borderTopColor: '#e9ecef',
paddingVertical: 12,
},
bottomButton: {
alignItems: 'center',
paddingHorizontal: 12,
},
bottomButtonText: {
fontSize: 12,
color: '#666',
marginTop: 4,
},
});
export default AdoptionList;

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

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

最后运行效果图如下显示:

本文介绍了一个基于React Native开发的狗狗领养中心应用,采用组件化架构设计,核心功能包括:
- 数据结构:定义完整的狗狗信息对象,包含基本信息、特征、领养状态等
- 组件设计:
- 可复用的DogCard组件展示单个狗狗信息
- AdoptionList组件作为容器管理状态和列表渲染
- 状态管理:使用useState管理收藏状态和领养操作
- 交互设计:实现收藏切换和领养申请功能
- 布局优化:采用卡片式设计,支持响应式布局
该应用展示了React Native开发的核心技术,包括组件复用、状态管理和交互设计等关键实践。
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。
更多推荐

所有评论(0)