135.[HarmonyOS NEXT 实战案例七:List系列] 水平列表组件实战:打造精美图片库 基础篇
[HarmonyOS NEXT 实战案例七:List系列] 水平列表组件实战:打造精美图片库 基础篇
项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star
效果演示
一、水平列表概述
在HarmonyOS NEXT应用开发中,除了常见的垂直列表外,水平列表也是一种重要的UI组件,特别适合展示图片、卡片等内容。水平列表允许用户通过左右滑动浏览内容,在有限的屏幕空间内展示更多信息。
1.1 水平列表的应用场景
应用场景 | 说明 |
---|---|
图片库 | 展示照片集合,用户可以左右滑动浏览 |
商品推荐 | 在电商应用中展示推荐商品 |
视频列表 | 展示视频缩略图,用户可以选择感兴趣的视频 |
卡片集合 | 展示信用卡、会员卡等卡片信息 |
横向导航 | 作为应用内的横向导航菜单 |
1.2 水平列表与垂直列表的区别
特性 | 水平列表 | 垂直列表 |
---|---|---|
滚动方向 | 左右滚动 | 上下滚动 |
适用场景 | 图片展示、横向导航 | 长列表数据、聊天记录 |
实现方式 | 设置listDirection为Axis.Horizontal | 默认为Axis.Vertical |
多行支持 | 可通过lanes属性设置多行 | 单列多行 |
二、水平列表实战案例
在本案例中,我们将实现一个水平方向的图片库,展示风景照片及其标题。
2.1 数据模型定义
首先,我们需要定义图片的数据模型:
interface Image {
title: string
image: ResourceStr
}
这个接口定义了图片的两个属性:标题和图片资源。
2.2 数据准备
接下来,我们准备图片数据:
private images: Image[]= [
{ title: '风景照1', image: $r('app.media.big28') },
{ title: '风景照2', image: $r('app.media.big27') },
{ title: '风景照3', image: $r('app.media.big26') },
{ title: '风景照4', image: $r('app.media.big25') },
{ title: '风景照5', image: $r('app.media.big24') },
{ title: '风景照6', image: $r('app.media.big23') },
{ title: '风景照7', image: $r('app.media.big22') },
{ title: '风景照8', image: $r('app.media.big21') },
]
我们创建了一个包含8张风景照片的数组,每张照片都有标题和图片资源。
2.3 页面结构设计
整个页面采用垂直布局,包含标题栏和两个水平图片列表:
build() {
Column() {
// 标题栏
Row() {
Text('照片库')
.fontSize(24)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height(56)
.padding({ left: 16 })
.backgroundColor('#F1F3F5')
// 水平图片列表
List() {
// 列表内容
}
.width('100%')
.height(180)
.margin({ top: 16 })
.listDirection(Axis.Horizontal) // 设置为水平列表
.padding({ left: 16 })
// 标题栏
Row() {
Text('推荐照片')
.fontSize(20)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height(56)
.padding({ left: 16 })
.margin({ top: 16 })
// 多行水平图片列表
List() {
// 列表内容
}
.width('100%')
.layoutWeight(1)
.listDirection(Axis.Horizontal) // 设置为水平列表
.lanes(2) // 设置为2行
.padding({ left: 16 })
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
在这个结构中:
- 使用Column作为根容器,占满整个屏幕
- 顶部是一个Row容器,作为标题栏,包含标题文本
- 中间是第一个List组件,用于显示单行水平图片列表
- 接着是另一个标题栏
- 底部是第二个List组件,用于显示多行水平图片列表
2.4 单行水平列表实现
接下来,我们实现第一个水平列表的内容:
List() {
ForEach(this.images, (item:Image) => {
ListItem() {
Column() {
// 图片
Image(item.image)
.width(160)
.height(120)
.borderRadius(8)
.objectFit(ImageFit.Cover)
// 图片标题
Text(item.title)
.fontSize(14)
.margin({ top: 8 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.alignItems(HorizontalAlign.Center)
.width(160)
}
.padding({ right: 12 })
})
}
.width('100%')
.height(180)
.margin({ top: 16 })
.listDirection(Axis.Horizontal) // 设置为水平列表
.padding({ left: 16 })
在这段代码中:
- 使用ForEach遍历images数组,为每张图片创建一个ListItem
- 每个ListItem包含一个Column布局,用于垂直排列图片和标题
- 图片使用Image组件,设置宽高和圆角
- 标题使用Text组件,设置最大行数和文本溢出处理
- 设置ListItem的右侧内边距,使列表项之间有间隔
- 最重要的是,通过listDirection(Axis.Horizontal)将列表方向设置为水平
2.5 多行水平列表实现
接下来,我们实现第二个水平列表,这是一个多行水平列表:
List() {
ForEach(this.images, (item:Image) => {
ListItem() {
Column() {
// 图片
Image(item.image)
.width(120)
.height(90)
.borderRadius(8)
.objectFit(ImageFit.Cover)
// 图片标题
Text(item.title)
.fontSize(14)
.margin({ top: 8 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.alignItems(HorizontalAlign.Center)
.width(120)
}
.padding({ right: 12, bottom: 16 })
})
}
.width('100%')
.layoutWeight(1)
.listDirection(Axis.Horizontal) // 设置为水平列表
.lanes(2) // 设置为2行
.padding({ left: 16 })
这个列表与第一个列表的主要区别在于:
- 图片和列表项的尺寸略小
- 添加了底部内边距,使行与行之间有间隔
- 最重要的是,通过lanes(2)属性将列表设置为2行
三、水平列表的关键属性解析
3.1 listDirection属性
listDirection属性用于设置列表的滚动方向,是实现水平列表的关键属性:
.listDirection(Axis.Horizontal) // 设置为水平列表
Axis枚举值说明:
值 | 说明 |
---|---|
Axis.Horizontal | 水平方向,列表项从左到右排列 |
Axis.Vertical | 垂直方向,列表项从上到下排列(默认值) |
3.2 lanes属性
lanes属性用于设置水平列表的行数或垂直列表的列数:
.lanes(2) // 设置为2行
当listDirection为Axis.Horizontal时,lanes表示行数;当listDirection为Axis.Vertical时,lanes表示列数。
3.3 列表项宽度设置
在水平列表中,列表项的宽度是一个重要的设置:
Column() {
// 图片和标题
}
.alignItems(HorizontalAlign.Center)
.width(160) // 设置列表项内容的宽度
需要注意的是,这里设置的是列表项内容的宽度,而不是ListItem本身的宽度。ListItem的宽度会根据内容自动调整。
3.4 列表项间距设置
为了使列表项之间有适当的间距,我们可以设置ListItem的内边距:
ListItem() {
// 列表项内容
}
.padding({ right: 12 }) // 设置右侧内边距
在水平列表中,通常设置右侧内边距来控制列表项之间的水平间距;在多行水平列表中,还需要设置底部内边距来控制行与行之间的垂直间距。
四、完整代码解析
让我们来看一下完整的代码实现:
@Component
export struct HorizontalList {
// 图片数据
private images: Image[]= [
{ title: '风景照1', image: $r('app.media.big28') },
{ title: '风景照2', image: $r('app.media.big27') },
{ title: '风景照3', image: $r('app.media.big26') },
{ title: '风景照4', image: $r('app.media.big25') },
{ title: '风景照5', image: $r('app.media.big24') },
{ title: '风景照6', image: $r('app.media.big23') },
{ title: '风景照7', image: $r('app.media.big22') },
{ title: '风景照8', image: $r('app.media.big21') },
]
build() {
Column() {
// 标题栏
Row() {
Text('照片库')
.fontSize(24)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height(56)
.padding({ left: 16 })
.backgroundColor('#F1F3F5')
// 水平图片列表
List() {
ForEach(this.images, (item:Image) => {
ListItem() {
Column() {
// 图片
Image(item.image)
.width(160)
.height(120)
.borderRadius(8)
.objectFit(ImageFit.Cover)
// 图片标题
Text(item.title)
.fontSize(14)
.margin({ top: 8 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.alignItems(HorizontalAlign.Center)
.width(160)
}
.padding({ right: 12 })
})
}
.width('100%')
.height(180)
.margin({ top: 16 })
.listDirection(Axis.Horizontal) // 设置为水平列表
.padding({ left: 16 })
// 标题栏
Row() {
Text('推荐照片')
.fontSize(20)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height(56)
.padding({ left: 16 })
.margin({ top: 16 })
// 多行水平图片列表
List() {
ForEach(this.images, (item:Image) => {
ListItem() {
Column() {
// 图片
Image(item.image)
.width(120)
.height(90)
.borderRadius(8)
.objectFit(ImageFit.Cover)
// 图片标题
Text(item.title)
.fontSize(14)
.margin({ top: 8 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.alignItems(HorizontalAlign.Center)
.width(120)
}
.padding({ right: 12, bottom: 16 })
})
}
.width('100%')
.layoutWeight(1)
.listDirection(Axis.Horizontal) // 设置为水平列表
.lanes(2) // 设置为2行
.padding({ left: 16 })
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
4.1 代码结构分析
部分 | 说明 |
---|---|
@Component | 组件装饰器,表明这是一个自定义组件 |
private images | 私有属性,存储图片数据 |
build() | 组件的构建函数,定义组件的UI结构 |
Column | 根容器,垂直排列子元素 |
Row | 标题栏容器,水平排列子元素 |
List | 列表容器,用于展示图片列表 |
ForEach | 循环构建器,遍历图片数据 |
ListItem | 列表项容器,定义每个图片的布局 |
4.2 样式设置分析
在这个案例中,我们使用了多种样式设置来美化界面:
-
尺寸设置:
- 使用width('100%')和height('100%')使组件占满父容器
- 使用layoutWeight(1)使第二个List组件占据剩余空间
- 设置具体的像素值,如height(180)、width(160)等
-
边距和填充:
- 使用padding设置内边距
- 使用margin设置外边距
-
颜色和背景:
- 设置背景颜色backgroundColor
-
文本样式:
- 设置字体大小fontSize
- 设置字体粗细fontWeight
- 设置最大行数maxLines和文本溢出处理textOverflow
-
特殊效果:
- 使用borderRadius设置图片圆角效果
- 使用objectFit设置图片填充模式
总结
在本篇教程中,我们学习了如何使用HarmonyOS NEXT的List和ListItem组件创建水平方向的图片列表。我们从数据模型定义、页面结构设计到列表项实现,全面讲解了水平列表的实现过程。 水平列表是一种非常实用的UI组件,特别适合展示图片、卡片等内容。通过本教程的学习,你应该能够在自己的应用中灵活运用水平列表,创建出更加丰富和用户友好的界面。
- 0回答
- 4粉丝
- 0关注
- 136.[HarmonyOS NEXT 实战案例七:List系列] 水平列表组件实战:打造精美图片库 进阶篇
- 137.[HarmonyOS NEXT 实战案例七:List系列] 多列列表组件实战:打造精美应用推荐页 基础篇
- 138.[HarmonyOS NEXT 实战案例七:List系列] 多列列表组件实战:打造精美应用推荐页 进阶篇
- 151.[HarmonyOS NEXT 实战案例十二:List系列] 卡片样式列表组件实战:打造精美电商应用 基础篇
- [HarmonyOS NEXT 实战案例六:List系列] 垂直列表组件实战:打造高效联系人列表 基础篇
- 145.[HarmonyOS NEXT 实战案例七 :List系列] 可选择列表基础篇
- 152.[HarmonyOS NEXT 实战案例十二:List系列] 卡片样式列表组件实战:打造精美电商应用 进阶篇
- 141.[HarmonyOS NEXT 实战案例九:List系列] 分组列表组件实战:打造分类设置菜单 基础篇
- 139.[HarmonyOS NEXT 实战案例八:List系列] 滑动操作列表组件实战:打造高效待办事项应用 基础篇
- 143.[HarmonyOS NEXT 实战案例十:List系列] 字母索引列表组件实战:打造高效联系人应用 基础篇
- 146.[HarmonyOS NEXT 实战案例七 :List系列] 可选择列表进阶篇
- 147.[HarmonyOS NEXT 实战案例八 :List系列] 粘性头部列表基础篇
- 155.[HarmonyOS NEXT 实战案例十二 :List系列] 聊天消息列表 - 基础篇
- 134.[HarmonyOS NEXT 实战案例六:List系列] 垂直列表组件实战:打造高效联系人列表 进阶篇
- 142.[HarmonyOS NEXT 实战案例九:List系列] 分组列表组件实战:打造分类设置菜单 进阶篇