137.[HarmonyOS NEXT 实战案例七:List系列] 多列列表组件实战:打造精美应用推荐页 基础篇
[HarmonyOS NEXT 实战案例七:List系列] 多列列表组件实战:打造精美应用推荐页 基础篇
项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star
效果演示
一、多列列表基础介绍
在HarmonyOS NEXT应用开发中,多列列表是一种常见的UI布局方式,特别适合展示网格状的内容,如应用商店、图片库、商品展示等。多列列表可以在有限的屏幕空间内高效地展示更多内容,提升用户体验。
1.1 多列列表的特点
特点 | 说明 |
---|---|
网格布局 | 内容以网格形式排列,可同时展示多个列表项 |
高效利用空间 | 在同一屏幕空间内可展示更多内容 |
灵活的列数设置 | 可根据屏幕大小和内容特点设置不同的列数 |
支持分割线 | 可添加网格分割线,使界面更加清晰 |
自适应布局 | 可根据屏幕方向和大小自动调整布局 |
1.2 多列列表的实现方式
在HarmonyOS NEXT中,实现多列列表主要有两种方式:
- 使用List组件的lanes属性:通过设置List组件的lanes属性,可以将列表项排列为多列布局。
- 使用Grid组件:Grid组件专门用于创建网格布局,适合更复杂的网格需求。
在本教程中,我们将重点介绍使用List组件的lanes属性实现多列列表。
二、多列列表实战案例
在本案例中,我们将实现一个应用推荐页面,以多列网格的形式展示应用信息,包括应用图标、名称和下载量。
2.1 数据模型定义
首先,我们需要定义应用的数据模型:
interface AppType {
name: string;
icon: Resource;
downloads: string;
}
这个接口定义了应用的三个属性:名称、图标和下载量。其中图标使用Resource类型,表示资源引用。
2.2 数据准备
接下来,我们准备应用数据:
private apps: AppType[] = [
{ name: '音乐播放器', icon: $r("app.media.music_icon"), downloads: '1000万+' },
{ name: '视频播放器', icon: $r('app.media.video_icon_videos'), downloads: '500万+' },
{ name: '图片编辑器', icon: $r('app.media.photo_icon'), downloads: '300万+' },
{ name: '日历', icon: $r('app.media.calendar'), downloads: '800万+' },
{ name: '天气', icon: $r('app.media.active_weather_icon'), downloads: '1200万+' },
{ name: '计算器', icon: $r('app.media.mobile_calculator_ap'), downloads: '600万+' },
{ name: '备忘录', icon: $r("app.media.note_icon"), downloads: '400万+' },
{ name: '地图', icon: $r('app.media.map_icon2'), downloads: '900万+' },
{ name: '电子书', icon: $r("app.media.Facebook_icon_03"), downloads: '200万+' },
{ name: '购物', icon: $r('app.media.Shopping_icon'), downloads: '700万+' },
{ name: '游戏中心', icon: $r("app.media.game_icon"), downloads: '1500万+' },
{ name: '健康', icon: $r("app.media.dcc_health_icon"), downloads: '350万+' },
]
我们创建了一个包含12个应用的数组,每个应用都有名称、图标资源和下载量信息。
2.3 页面结构设计
整个页面采用垂直布局,包含标题栏、应用列表和底部导航栏三部分:
build() {
Column() {
// 标题栏
Row() {
Text('应用推荐')
.fontSize(24)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height(56)
.padding({ left: 16 })
.backgroundColor('#F1F3F5')
// 多列应用列表
List() {
// 列表内容
}
.width('100%')
.layoutWeight(1)
.lanes(3) // 设置为3列布局
.divider({ // 设置网格分割线
strokeWidth: 1,
color: '#E5E5E5',
startMargin: 8,
endMargin: 8
})
// 底部导航栏
Row() {
// 导航栏内容
}
.width('100%')
.height(60)
.padding({ top: 8, bottom: 8 })
.backgroundColor('#FFFFFF')
.borderColor('#E5E5E5')
.borderWidth({ top: 1 })
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
在这个结构中:
- 使用Column作为根容器,占满整个屏幕
- 顶部是一个Row容器,作为标题栏,包含标题文本
- 中间是List组件,用于显示应用列表,设置lanes(3)使其成为3列布局
- 底部是一个Row容器,作为导航栏
2.4 列表项实现
接下来,我们实现列表项的内容:
List() {
ForEach(this.apps, (app:AppType) => {
ListItem() {
Column() {
// 应用图标
Image(app.icon)
.width(60)
.height(60)
.borderRadius(12)
// 应用名称
Text(app.name)
.width(100)
.fontSize(14)
.margin({ top: 8 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
// 下载量
Text(app.downloads)
.width(100)
.fontSize(12)
.fontColor('#666666')
.margin({ top: 4 })
}
.alignItems(HorizontalAlign.Center)
.width('100%')
.padding(12)
}
.width('33%') // 每个项目占用1/3的宽度
.padding(8)
})
}
在这段代码中:
- 使用ForEach遍历apps数组,为每个应用创建一个ListItem
- 每个ListItem包含一个Column布局,用于垂直排列应用图标、名称和下载量
- 应用图标使用Image组件,设置为圆角矩形(通过borderRadius实现)
- 应用名称和下载量使用Text组件,设置不同的字体大小和颜色
- 设置ListItem的宽度为'33%',使每行显示3个应用
2.5 底部导航栏实现
最后,我们实现底部导航栏:
Row() {
Column() {
Image($r('app.media.01'))
.width(24)
.height(24)
Text('首页')
.fontSize(12)
.margin({ top: 4 })
}
.layoutWeight(1)
Column() {
Image($r('app.media.02'))
.width(24)
.height(24)
Text('分类')
.fontSize(12)
.margin({ top: 4 })
}
.layoutWeight(1)
Column() {
Image($r('app.media.03'))
.width(24)
.height(24)
Text('排行')
.fontSize(12)
.margin({ top: 4 })
.fontColor('#007DFF')
}
.layoutWeight(1)
Column() {
Image($r('app.media.04'))
.width(24)
.height(24)
Text('我的')
.fontSize(12)
.margin({ top: 4 })
}
.layoutWeight(1)
}
在这段代码中:
- 使用Row作为导航栏的容器,包含4个Column子容器
- 每个Column代表一个导航项,包含一个图标和一个文本
- 使用layoutWeight(1)使4个导航项平均分配空间
- 为当前选中的导航项(排行)设置特殊的文本颜色
三、完整代码解析
让我们来看一下完整的代码实现:
@Component
export struct MultiColumnList {
// 应用数据
private apps: AppType[] = [
{ name: '音乐播放器', icon: $r("app.media.music_icon"), downloads: '1000万+' },
{ name: '视频播放器', icon: $r('app.media.video_icon_videos'), downloads: '500万+' },
{ name: '图片编辑器', icon: $r('app.media.photo_icon'), downloads: '300万+' },
{ name: '日历', icon: $r('app.media.calendar'), downloads: '800万+' },
{ name: '天气', icon: $r('app.media.active_weather_icon'), downloads: '1200万+' },
{ name: '计算器', icon: $r('app.media.mobile_calculator_ap'), downloads: '600万+' },
{ name: '备忘录', icon: $r("app.media.note_icon"), downloads: '400万+' },
{ name: '地图', icon: $r('app.media.map_icon2'), downloads: '900万+' },
{ name: '电子书', icon: $r("app.media.Facebook_icon_03"), downloads: '200万+' },
{ name: '购物', icon: $r('app.media.Shopping_icon'), downloads: '700万+' },
{ name: '游戏中心', icon: $r("app.media.game_icon"), downloads: '1500万+' },
{ name: '健康', icon: $r("app.media.dcc_health_icon"), downloads: '350万+' },
]
build() {
Column() {
// 标题栏
Row() {
Text('应用推荐')
.fontSize(24)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height(56)
.padding({ left: 16 })
.backgroundColor('#F1F3F5')
// 多列应用列表
List() {
ForEach(this.apps, (app:AppType) => {
ListItem() {
Column() {
// 应用图标
Image(app.icon)
.width(60)
.height(60)
.borderRadius(12)
// 应用名称
Text(app.name)
.width(100)
.fontSize(14)
.margin({ top: 8 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
// 下载量
Text(app.downloads)
.width(100)
.fontSize(12)
.fontColor('#666666')
.margin({ top: 4 })
}
.alignItems(HorizontalAlign.Center)
.width('100%')
.padding(12)
}
.width('33%') // 每个项目占用1/3的宽度
.padding(8)
})
}
.width('100%')
.layoutWeight(1)
.lanes(3) // 设置为3列布局
.divider({ // 设置网格分割线
strokeWidth: 1,
color: '#E5E5E5',
startMargin: 8,
endMargin: 8
})
// 底部导航栏
Row() {
Column() {
Image($r('app.media.01'))
.width(24)
.height(24)
Text('首页')
.fontSize(12)
.margin({ top: 4 })
}
.layoutWeight(1)
Column() {
Image($r('app.media.02'))
.width(24)
.height(24)
Text('分类')
.fontSize(12)
.margin({ top: 4 })
}
.layoutWeight(1)
Column() {
Image($r('app.media.03'))
.width(24)
.height(24)
Text('排行')
.fontSize(12)
.margin({ top: 4 })
.fontColor('#007DFF')
}
.layoutWeight(1)
Column() {
Image($r('app.media.04'))
.width(24)
.height(24)
Text('我的')
.fontSize(12)
.margin({ top: 4 })
}
.layoutWeight(1)
}
.width('100%')
.height(60)
.padding({ top: 8, bottom: 8 })
.backgroundColor('#FFFFFF')
.borderColor('#E5E5E5')
.borderWidth({ top: 1 })
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
3.1 代码结构分析
部分 | 说明 |
---|---|
@Component | 组件装饰器,表明这是一个自定义组件 |
private apps | 私有属性,存储应用数据 |
build() | 组件的构建函数,定义组件的UI结构 |
Column | 根容器,垂直排列子元素 |
Row | 标题栏和底部导航栏容器,水平排列子元素 |
List | 列表容器,用于展示应用列表 |
ForEach | 循环构建器,遍历应用数据 |
ListItem | 列表项容器,定义每个应用的布局 |
3.2 样式设置分析
在这个案例中,我们使用了多种样式设置来美化界面:
-
尺寸设置:
- 使用width('100%')和height('100%')使组件占满父容器
- 使用layoutWeight(1)使List组件占据剩余空间
- 设置具体的像素值,如height(56)、width(60)等
- 使用width('33%')设置列表项宽度为容器的1/3
-
边距和填充:
- 使用padding设置内边距
- 使用margin设置外边距
-
颜色和背景:
- 设置背景颜色backgroundColor
- 设置文本颜色fontColor
- 设置边框颜色borderColor
-
文本样式:
- 设置字体大小fontSize
- 设置字体粗细fontWeight
- 使用maxLines和textOverflow处理文本溢出
-
特殊效果:
- 使用borderRadius设置圆角效果
- 使用divider设置分割线
- 使用borderWidth设置边框宽度
3.3 多列列表关键属性
实现多列列表的关键在于以下几个属性:
-
lanes属性:
.lanes(3) // 设置为3列布局
lanes属性指定了列表的列数,在本例中设置为3,表示列表项将排列为3列。
-
列表项宽度:
.width('33%') // 每个项目占用1/3的宽度
为了使列表项能够正确排列,需要设置每个ListItem的宽度。在3列布局中,每个列表项的宽度设置为'33%',表示占用容器宽度的1/3。
-
网格分割线:
.divider({ // 设置网格分割线 strokeWidth: 1, color: '#E5E5E5', startMargin: 8, endMargin: 8 })
divider属性用于设置列表的分割线。在多列列表中,分割线会形成网格状,使界面更加清晰。
总结
在本篇教程中,我们学习了如何使用HarmonyOS NEXT的List组件的lanes属性创建多列列表,实现了一个应用推荐页面。我们从数据模型定义、页面结构设计、列表项实现到底部导航栏实现,全面讲解了多列列表的实现过程。
- 0回答
- 4粉丝
- 0关注
- 138.[HarmonyOS NEXT 实战案例七:List系列] 多列列表组件实战:打造精美应用推荐页 进阶篇
- 135.[HarmonyOS NEXT 实战案例七:List系列] 水平列表组件实战:打造精美图片库 基础篇
- 151.[HarmonyOS NEXT 实战案例十二:List系列] 卡片样式列表组件实战:打造精美电商应用 基础篇
- 136.[HarmonyOS NEXT 实战案例七:List系列] 水平列表组件实战:打造精美图片库 进阶篇
- 152.[HarmonyOS NEXT 实战案例十二:List系列] 卡片样式列表组件实战:打造精美电商应用 进阶篇
- [HarmonyOS NEXT 实战案例六:List系列] 垂直列表组件实战:打造高效联系人列表 基础篇
- 145.[HarmonyOS NEXT 实战案例七 :List系列] 可选择列表基础篇
- 141.[HarmonyOS NEXT 实战案例九:List系列] 分组列表组件实战:打造分类设置菜单 基础篇
- 139.[HarmonyOS NEXT 实战案例八:List系列] 滑动操作列表组件实战:打造高效待办事项应用 基础篇
- 143.[HarmonyOS NEXT 实战案例十:List系列] 字母索引列表组件实战:打造高效联系人应用 基础篇
- 149.[HarmonyOS NEXT 实战案例十一:List系列] 下拉刷新和上拉加载更多列表组件实战:打造高效新闻应用 基础篇
- 146.[HarmonyOS NEXT 实战案例七 :List系列] 可选择列表进阶篇
- 147.[HarmonyOS NEXT 实战案例八 :List系列] 粘性头部列表基础篇
- 155.[HarmonyOS NEXT 实战案例十二 :List系列] 聊天消息列表 - 基础篇
- 134.[HarmonyOS NEXT 实战案例六:List系列] 垂直列表组件实战:打造高效联系人列表 进阶篇