[HarmonyOS NEXT 实战案例:旅行应用] 进阶篇 - 旅行规划应用的交互功能与状态管理
[HarmonyOS NEXT 实战案例:旅行应用] 进阶篇 - 旅行规划应用的交互功能与状态管理
项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star
效果演示
引言
在基础篇中,我们学习了如何使用HarmonyOS NEXT的RowSplit
组件构建旅行规划应用的基本布局。在本篇进阶教程中,我们将深入探讨旅行规划应用的交互功能和状态管理,包括行程切换、视图模式切换、数据绑定等高级特性。通过掌握这些进阶技巧,你将能够构建出更加实用和用户友好的旅行规划应用。
状态管理概述
在HarmonyOS NEXT中,状态管理是实现交互功能的关键。在我们的旅行规划应用中,主要使用了以下状态变量:
@State selectedDay: number = 0
@State showMap: boolean = false
@State tripDays: TripDay[] = [ /* ... */ ]
这些状态变量的作用如下:
selectedDay
:记录当前选中的行程索引,初始值为0(第一天)showMap
:控制是否显示地图视图,初始值为false(显示详情视图)tripDays
:存储所有行程数据,包含多天的行程信息
数据模型与绑定
数据模型定义
在旅行规划应用中,我们定义了两个接口来描述数据结构:
interface TripDay {
day: string
date: string
location: string
description: string
hotel: string
restaurant: string
image: Resource
activities: Activity[]
}
interface Activity {
time: string
title: string
icon: Resource
}
这种清晰的数据模型定义有助于我们理解和管理应用的数据流。
数据绑定
在HarmonyOS NEXT中,数据绑定是通过状态变量和UI组件的属性绑定来实现的。以下是一些数据绑定的示例:
1. 行程列表项的选中状态
.backgroundColor(index === this.selectedDay ? '#e8f5e9' : 'transparent')
这里,我们根据index
是否等于selectedDay
来决定行程列表项的背景色,实现选中效果。
2. 详情区域标题
Text(this.tripDays[this.selectedDay].day + ' · ' + this.tripDays[this.selectedDay].location)
这里,我们根据selectedDay
索引从tripDays
数组中获取当前选中行程的信息,并显示在标题中。
3. 切换按钮图标
Image(this.showMap ? $r('app.media.big15') : $r('app.media.big14'))
这里,我们根据showMap
状态来决定显示哪个图标,实现切换效果。
交互功能实现
1. 行程切换功能
行程切换功能是通过点击左侧行程列表项来实现的:
ForEach(this.tripDays, (item: TripDay, index: number) => {
Column() {
// 行程列表项内容
}
.onClick(() => this.selectedDay = index)
})
当用户点击一个行程列表项时,会执行.onClick(() => this.selectedDay = index)
回调函数,更新selectedDay
状态变量。由于selectedDay
是一个@State
装饰的状态变量,它的变化会触发UI的自动更新,从而实现行程切换功能。
具体的更新包括:
- 左侧行程列表项的选中状态(背景色)更新
- 右侧详情区域的内容更新,包括标题、图片、描述、活动列表、住宿和餐饮信息
2. 视图模式切换功能
视图模式切换功能是通过点击右侧详情区域顶部的切换按钮来实现的:
Image(this.showMap ? $r('app.media.big15') : $r('app.media.big14'))
.onClick(() => this.showMap = !this.showMap)
当用户点击切换按钮时,会执行.onClick(() => this.showMap = !this.showMap)
回调函数,切换showMap
状态变量。由于showMap
是一个@State
装饰的状态变量,它的变化会触发UI的自动更新,从而实现视图模式切换功能。
具体的更新包括:
- 切换按钮图标的更新
- 右侧详情区域内容的更新,在地图视图和详情视图之间切换
3. 条件渲染
条件渲染是实现视图模式切换的关键技术。在右侧详情区域,我们使用条件语句根据showMap
状态来决定显示地图视图还是详情视图:
if (this.showMap) {
// 地图视图
Column() {
Image($r('app.media.big13'))
.width('100%')
.height(300)
.objectFit(ImageFit.Cover)
.borderRadius(8)
Text('地图位置')
.fontSize(16)
.margin({ top: 15 })
}
.height('100%')
} else {
// 详情视图
Scroll() {
Column() {
// 详情视图内容
}
}
}
当showMap
为true
时,显示地图视图;当showMap
为false
时,显示详情视图。这种条件渲染方式使我们能够在同一个区域显示不同的内容,提高界面的灵活性。
高级状态管理
1. 状态派生
状态派生是指根据一个或多个状态变量计算出新的值。在我们的旅行规划应用中,有多处使用了状态派生:
// 根据selectedDay派生当前行程信息
const currentTrip = this.tripDays[this.selectedDay];
// 派生标题文本
Text(currentTrip.day + ' · ' + currentTrip.location)
// 派生切换按钮图标
Image(this.showMap ? $r('app.media.big15') : $r('app.media.big14'))
状态派生使我们能够根据基本状态计算出更复杂的值,简化代码逻辑。
2. 状态更新与UI刷新
在HarmonyOS NEXT中,当@State
装饰的状态变量发生变化时,框架会自动触发UI的更新。这种响应式的状态管理机制使我们能够专注于状态的变化,而不需要手动更新UI。
例如,当用户点击行程列表项时,我们只需要更新selectedDay
状态:
.onClick(() => this.selectedDay = index)
框架会自动检测到selectedDay
的变化,并更新所有依赖于它的UI部分,包括行程列表项的选中状态和右侧详情区域的内容。
3. 组合状态
组合状态是指多个状态变量共同决定UI的显示。在我们的旅行规划应用中,右侧详情区域的内容是由selectedDay
和showMap
两个状态变量共同决定的:
selectedDay
决定显示哪一天的行程信息showMap
决定是显示地图视图还是详情视图
这种组合状态使我们能够实现更复杂的UI逻辑,提高应用的交互性。
实战案例:添加新功能
1. 添加行程收藏功能
让我们为旅行规划应用添加一个行程收藏功能。首先,我们需要在TripDay
接口中添加一个favorite
字段:
interface TripDay {
day: string
date: string
location: string
description: string
hotel: string
restaurant: string
image: Resource
activities: Activity[]
favorite: boolean // 新增字段
}
然后,在右侧详情区域的顶部操作栏中添加一个收藏按钮:
Row() {
Text(this.tripDays[this.selectedDay].day + ' · ' + this.tripDays[this.selectedDay].location)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
// 收藏按钮
Image(this.tripDays[this.selectedDay].favorite ? $r('app.media.favorite_filled') : $r('app.media.favorite_outline'))
.width(24)
.height(24)
.margin({ right: 10 })
.onClick(() => {
// 创建一个新的数组,避免直接修改状态
const newTripDays = [...this.tripDays];
newTripDays[this.selectedDay].favorite = !newTripDays[this.selectedDay].favorite;
this.tripDays = newTripDays;
})
Image(this.showMap ? $r('app.media.big15') : $r('app.media.big14'))
.width(24)
.height(24)
.onClick(() => this.showMap = !this.showMap)
}
这样,用户就可以通过点击收藏按钮来收藏或取消收藏当前行程了。
2. 添加行程筛选功能
让我们为旅行规划应用添加一个行程筛选功能,允许用户筛选出收藏的行程。首先,我们需要添加一个新的状态变量:
@State showFavoritesOnly: boolean = false
然后,在左侧行程列表区域的顶部添加一个筛选按钮:
Row() {
Text('我的行程')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
// 筛选按钮
Image(this.showFavoritesOnly ? $r('app.media.filter_on') : $r('app.media.filter_off'))
.width(24)
.height(24)
.onClick(() => this.showFavoritesOnly = !this.showFavoritesOnly)
}
.width('100%')
.margin({ top: 20, bottom: 15 })
最后,修改行程列表的渲染逻辑,根据筛选条件显示行程:
ForEach(this.tripDays.filter(trip => !this.showFavoritesOnly || trip.favorite), (item: TripDay, index: number) => {
// 行程列表项内容
})
这样,当用户点击筛选按钮时,可以切换显示所有行程或只显示收藏的行程。
小结
在本教程中,我们深入探讨了旅行规划应用的交互功能和状态管理。通过使用@State
装饰器定义状态变量,我们实现了行程切换、视图模式切换等交互功能。我们还学习了状态派生、状态更新与UI刷新、组合状态等高级状态管理技巧,以及如何添加行程收藏和筛选功能。
- 0回答
- 4粉丝
- 0关注
- [HarmonyOS NEXT 实战案例:聊天应用] 进阶篇 - 交互功能与状态管理
- [HarmonyOS NEXT 实战案例:电商应用] 进阶篇 - 交互功能与状态管理
- [HarmonyOS NEXT 实战案例:新闻阅读应用] 进阶篇 - 交互功能与状态管理
- [HarmonyOS NEXT 实战案例:电商应用] 进阶篇 - 交互功能与状态管理
- [HarmonyOS NEXT 实战案例:设置页面] 进阶篇 - 交互功能与状态管理
- [HarmonyOS NEXT 实战案例:文件管理器] 进阶篇 - 交互功能与状态管理
- [HarmonyOS NEXT 实战案例:教育应用] 进阶篇 - 课程学习平台的交互功能与状态管理
- [HarmonyOS NEXT 实战案例:健康应用] 进阶篇 - 健康数据仪表盘的交互功能与状态管理
- [HarmonyOS NEXT 实战案例:旅行应用] 基础篇 - 水平分割布局打造旅行规划应用
- [HarmonyOS NEXT 实战案例:音乐播放器] 进阶篇 - 交互式音乐播放器的状态管理与控制
- [HarmonyOS NEXT 实战案例:分割布局] 进阶篇 - 交互式邮件应用布局
- [HarmonyOS NEXT 实战案例:分割布局] 进阶篇 - RowSplit与ColumnSplit的组合应用
- 98.[HarmonyOS NEXT 实战案例:分割布局] 高级篇 - 邮件应用的高级功能与优化
- [HarmonyOS NEXT 实战案例十八] 日历日程视图网格布局(进阶篇)
- [HarmonyOS NEXT 实战案例三:SideBarContainer] 侧边栏容器实战:社交应用联系人列表 进阶篇