[HarmonyOS NEXT 实战案例八] 电影票务网格布局(上)
[HarmonyOS NEXT 实战案例八] 电影票务网格布局(上)
项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star
效果演示
1. 概述
在移动应用开发中,电影票务应用是一个常见的场景,用户可以通过应用查看正在热映的电影信息,并进行选座购票等操作。本教程将详细讲解如何使用HarmonyOS NEXT的GridRow和GridCol组件实现电影票务应用中的电影列表网格布局,帮助开发者掌握网格布局的基本用法和实现技巧。
本教程将涵盖以下内容:
- 电影数据结构设计
- 电影列表网格布局实现
- GridRow和GridCol组件详解
- 电影卡片UI设计与实现
2. 数据结构设计
在实现电影票务网格布局之前,我们需要先定义电影数据的结构。在本案例中,我们定义了一个MovieType
接口,包含电影的基本信息:
interface MovieType {
title: string; // 电影标题
rating: number; // 电影评分
poster: Resource; // 电影海报
type: string; // 电影类型
}
这个接口定义了电影的四个基本属性:
title
:电影标题,字符串类型rating
:电影评分,数字类型poster
:电影海报,Resource类型(HarmonyOS中的资源引用类型)type
:电影类型,字符串类型(如科幻、动画、悬疑等)
3. 数据准备
定义好数据结构后,我们需要准备一些电影数据用于展示。在本案例中,我们在组件内部定义了一个电影数据数组:
private movies:MovieType[] = [
{ title: '流浪地球3', rating: 9.2, poster: $r("app.media.big7"), type: '科幻' },
{ title: '长安三万里', rating: 8.8, poster: $r("app.media.big5"), type: '动画' },
{ title: '消失的她', rating: 8.5, poster: $r("app.media.big1"), type: '悬疑' },
{ title: '封神第一部', rating: 8.9, poster: $r("app.media.big1"), type: '奇幻' }
]
这里我们准备了4部电影的数据,包括电影标题、评分、海报和类型。海报使用$r()
方法引用应用资源。在实际应用中,这些数据通常会从服务器获取。
4. 布局实现
4.1 整体布局结构
电影票务网格布局的整体结构如下:
build() {
Column() {
Text('正在热映')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 16 })
.width('100%')
.textAlign(TextAlign.Start)
GridRow({ columns: 2, gutter: 16 }) {
// 电影网格内容
}
}
.width('100%')
.padding(16)
}
整体布局使用一个Column容器,包含两个主要部分:
- 标题文本:显示"正在热映",使用Text组件实现
- 电影网格:使用GridRow和GridCol组件实现
4.2 GridRow和GridCol配置
在本案例中,我们使用GridRow和GridCol组件实现电影网格布局:
GridRow({ columns: 2, gutter: 16 }) {
ForEach(this.movies, (movie:MovieType) => {
GridCol({ span: 1 }) {
// 电影卡片内容
}
})
}
GridRow组件的配置:
columns: 2
:设置网格为2列布局gutter: 16
:设置网格项之间的间距为16vp
GridCol组件的配置:
span: 1
:每个电影卡片占据1列的宽度
使用ForEach循环遍历电影数据数组,为每部电影创建一个GridCol网格项。
4.3 电影卡片实现
每个电影卡片的内部结构如下:
Column() {
Image(movie.poster)
.width('100%')
.aspectRatio(0.7)
.borderRadius(8)
Text(movie.title)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.margin({ top: 8 })
.width('100%')
.textAlign(TextAlign.Start)
Row() {
Text(movie.type)
.fontSize(12)
.fontColor('#9E9E9E')
Row() {
Image($r("app.media.heart_filled"))
.width(12)
.height(12)
.margin({ right: 4 })
Text(movie.rating.toFixed(1))
.fontSize(12)
}
.margin({ left: 8 })
}
.width('100%')
.margin({ top: 4 })
.justifyContent(FlexAlign.SpaceBetween)
}
电影卡片使用Column容器,包含三个主要部分:
- 电影海报:使用Image组件显示,设置宽度为100%,高宽比为0.7,圆角为8vp
- 电影标题:使用Text组件显示,字体大小为16fp,字体粗细为Medium,顶部外边距为8vp
- 电影信息行:使用Row容器,包含电影类型和评分两部分,两者之间使用SpaceBetween对齐方式
电影类型使用Text组件显示,字体大小为12fp,颜色为灰色(#9E9E9E)。
电影评分部分使用Row容器,包含一个心形图标和评分文本,评分文本使用toFixed(1)
方法保留一位小数。
5. GridRow和GridCol组件详解
5.1 GridRow组件
GridRow是HarmonyOS NEXT提供的网格行容器组件,用于创建网格布局。它的主要属性包括:
属性名 | 类型 | 描述 |
---|---|---|
columns | number | GridColumns | 设置当前行列数 |
gutter | Length | GutterOption | 设置列间距 |
breakpoints | BreakPoints | 设置断点值 |
direction | GridRowDirection | 设置布局方向,默认为GridRowDirection.Row |
其中,GridColumns类型定义如下:
type GridColumns = {
xs?: number; // 极小尺寸断点下的列数
sm?: number; // 小尺寸断点下的列数
md?: number; // 中尺寸断点下的列数
lg?: number; // 大尺寸断点下的列数
xl?: number; // 特大尺寸断点下的列数
xxl?: number; // 超大尺寸断点下的列数
}
GutterOption类型定义如下:
type GutterOption = {
x?: Length; // 横向间距
y?: Length; // 纵向间距
}
5.2 GridCol组件
GridCol是HarmonyOS NEXT提供的网格列容器组件,用于在GridRow中创建网格项。它的主要属性包括:
属性名 | 类型 | 描述 |
---|---|---|
span | number | GridColumnOption | 设置当前组件跨越的列数 |
offset | number | GridColumnOption | 设置当前组件的偏移列数 |
order | number | GridColumnOption | 设置当前组件的顺序 |
其中,GridColumnOption类型定义如下:
type GridColumnOption = {
xs?: number; // 极小尺寸断点下的值
sm?: number; // 小尺寸断点下的值
md?: number; // 中尺寸断点下的值
lg?: number; // 大尺寸断点下的值
xl?: number; // 特大尺寸断点下的值
xxl?: number; // 超大尺寸断点下的值
}
6. 布局效果分析
本案例实现的电影票务网格布局效果如下:
- 整体采用2列网格布局,每个电影卡片占据1列
- 电影卡片包含海报、标题、类型和评分信息
- 海报使用aspectRatio属性保持固定的高宽比,确保所有海报显示一致
- 电影类型和评分信息使用justifyContent(FlexAlign.SpaceBetween)实现两端对齐
这种布局方式有以下优点:
- 结构清晰,信息展示完整
- 适合在不同尺寸的屏幕上显示
- 用户可以快速浏览多部电影的基本信息
7. 完整代码
以下是电影票务网格布局的完整代码:
// 电影票务网格布局
interface MovieType {
title: string;
rating: number;
poster: Resource;
type: string;
}
@Component
export struct MovieTicketGrid {
private movies:MovieType[] = [
{ title: '流浪地球3', rating: 9.2, poster: $r("app.media.big7"), type: '科幻' },
{ title: '长安三万里', rating: 8.8, poster: $r("app.media.big5"), type: '动画' },
{ title: '消失的她', rating: 8.5, poster: $r("app.media.big1"), type: '悬疑' },
{ title: '封神第一部', rating: 8.9, poster: $r("app.media.big1"), type: '奇幻' }
]
build() {
Column() {
Text('正在热映')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 16 })
.width('100%')
.textAlign(TextAlign.Start)
GridRow({ columns: 2, gutter: 16 }) {
ForEach(this.movies, (movie:MovieType) => {
GridCol({ span: 1 }) {
Column() {
Image(movie.poster)
.width('100%')
.aspectRatio(0.7)
.borderRadius(8)
Text(movie.title)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.margin({ top: 8 })
.width('100%')
.textAlign(TextAlign.Start)
Row() {
Text(movie.type)
.fontSize(12)
.fontColor('#9E9E9E')
Row() {
Image($r("app.media.heart_filled"))
.width(12)
.height(12)
.margin({ right: 4 })
Text(movie.rating.toFixed(1))
.fontSize(12)
}
.margin({ left: 8 })
}
.width('100%')
.margin({ top: 4 })
.justifyContent(FlexAlign.SpaceBetween)
}
}
})
}
}
.width('100%')
.padding(16)
}
}
8. 总结
本教程详细讲解了如何使用HarmonyOS NEXT的GridRow和GridCol组件实现电影票务应用中的电影列表网格布局。通过本教程,你应该已经掌握了:
- 如何定义和准备电影数据
- 如何使用GridRow和GridCol组件创建网格布局
- 如何设计和实现电影卡片UI
- GridRow和GridCol组件的主要属性和用法
在下一篇教程中,我们将在此基础上进一步优化电影票务网格布局,添加更多功能和交互效果,如电影详情页、购票功能等。
- 0回答
- 3粉丝
- 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 实战案例五] 社交应用照片墙网格布局(下)
- [HarmonyOS NEXT 实战案例一] 电商首页商品网格布局(下)
- [HarmonyOS NEXT 实战案例三] 音乐专辑网格展示(上)