145.[HarmonyOS NEXT 实战案例七 :List系列] 可选择列表基础篇
[HarmonyOS NEXT 实战案例七 :List系列] 可选择列表基础篇
项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star
效果演示
在移动应用开发中,可选择列表是一种常见且实用的交互模式,它允许用户从列表中选择一个或多个项目进行批量操作。本教程将详细讲解如何在HarmonyOS NEXT中实现一个功能完善的可选择列表,以文件管理应用为例,展示如何创建、管理和操作可选择列表。
一、可选择列表概述
可选择列表是List组件的一种特殊应用场景,它具有以下特点:
- 多选功能:允许用户同时选择多个列表项
- 选择模式切换:可以在普通浏览模式和选择模式之间切换
- 批量操作:对选中的项目执行批量操作,如删除、移动、分享等
- 全选/取消全选:提供快捷方式选择或取消选择所有项目
- 视觉反馈:通过UI变化清晰地指示当前选中的项目
二、数据模型设计
首先,我们需要定义文件数据的接口和示例数据:
interface FileType {
id: number,
name: string,
type: string,
size: string,
date: string,
icon: Resource
}
这个接口定义了文件的基本属性:
id
:文件的唯一标识符name
:文件名称type
:文件类型(如docx、xlsx、pdf等)size
:文件大小date
:修改日期icon
:文件图标资源
然后,我们创建示例文件数据:
private files: FileType[] = [
{ id: 1, name: '项目计划.docx', type: 'docx', size: '2.5MB', date: '2023-10-15', icon: $r('app.media.big26') },
{ id: 2, name: '财务报表.xlsx', type: 'xlsx', size: '1.8MB', date: '2023-10-14', icon: $r('app.media.big25') },
// 更多文件...
]
三、状态管理
为了管理可选择列表的状态,我们需要定义以下状态变量:
// 选中的文件ID列表
@State selectedIds: number[] = []
// 是否处于选择模式
@State isSelectMode: boolean = false
selectedIds
:存储当前选中的文件ID列表isSelectMode
:标记当前是否处于选择模式
四、核心功能实现
1. 切换选择模式
toggleSelectMode() {
this.isSelectMode = !this.isSelectMode
if (!this.isSelectMode) {
this.selectedIds = []
}
}
这个方法用于切换选择模式的开启和关闭。当退出选择模式时,会清空已选择的项目。
2. 切换选择状态
toggleSelection(id: number) {
const index = this.selectedIds.indexOf(id)
if (index === -1) {
this.selectedIds.push(id)
} else {
this.selectedIds.splice(index, 1)
}
}
这个方法用于切换单个文件的选择状态:如果文件未被选中,则添加到选中列表;如果已被选中,则从列表中移除。
3. 全选和取消全选
// 全选
selectAll() {
this.selectedIds = this.files.map(file => file.id)
}
// 取消全选
deselectAll() {
this.selectedIds = []
}
这两个方法分别用于全选和取消全选操作。
4. 获取文件图标
getFileIcon(type: string): Resource {
switch (type) {
case 'docx':
return $r('app.media.big26')
case 'xlsx':
return $r('app.media.big25')
// 其他文件类型...
default:
return $r('app.media.big20')
}
}
这个方法根据文件类型返回对应的图标资源。
五、UI构建
1. 整体布局
build() {
Column() {
// 标题栏
Row() { /* ... */ }
// 文件列表
List() { /* ... */ }
// 底部操作栏(选择模式下显示)
if (this.isSelectMode && this.selectedIds.length > 0) {
Row() { /* ... */ }
}
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
整体布局采用Column容器,包含三个主要部分:标题栏、文件列表和底部操作栏(仅在选择模式下且有选中项时显示)。
2. 标题栏实现
标题栏会根据当前是否处于选择模式显示不同的内容:
Row() {
if (this.isSelectMode) {
// 选择模式下的标题栏
Image($r('app.media.big2'))
.width(24)
.height(24)
.onClick(() => this.toggleSelectMode())
Text(`已选择 ${this.selectedIds.length} 项`)
.fontSize(18)
.fontWeight(FontWeight.Medium)
.margin({ left: 16 })
Blank()
Button(this.selectedIds.length === this.files.length ? '取消全选' : '全选')
.fontSize(14)
.fontColor('#007DFF')
.backgroundColor('transparent')
.onClick(() => {
if (this.selectedIds.length === this.files.length) {
this.deselectAll()
} else {
this.selectAll()
}
})
} else {
// 普通模式下的标题栏
Text('文件')
.fontSize(24)
.fontWeight(FontWeight.Bold)
Blank()
Image($r('app.media.01'))
.width(24)
.height(24)
.margin({ right: 16 })
Image($r('app.media.02'))
.width(24)
.height(24)
.margin({ right: 16 })
.onClick(() => this.toggleSelectMode())
}
}
.width('100%')
.height(56)
.padding({ left: 16, right: 16 })
.backgroundColor('#F1F3F5')
- 在选择模式下:显示返回按钮、已选择项数量和全选/取消全选按钮
- 在普通模式下:显示标题和操作按钮,包括进入选择模式的按钮
3. 文件列表实现
List() {
ForEach(this.files, (file: FileType) => {
ListItem() {
Row() {
if (this.isSelectMode) {
// 选择框
Checkbox({ name: file.id.toString() })
.select(this.selectedIds.includes(file.id))
.margin({ right: 16 })
.onChange((value) => {
this.toggleSelection(file.id)
})
}
// 文件图标
Image(this.getFileIcon(file.type))
.width(40)
.height(40)
.margin({ right: 16 })
// 文件信息
Column() {
Text(file.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
Row() {
Text(file.size)
.fontSize(14)
.fontColor('#666666')
Text(file.date)
.fontSize(14)
.fontColor('#666666')
.margin({ left: 16 })
}
.margin({ top: 4 })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
if (!this.isSelectMode) {
// 更多操作按钮
Image($r('app.media.game_icon'))
.width(24)
.height(24)
}
}
.width('100%')
.padding({ left: 16, right: 16, top: 12, bottom: 12 })
.onClick(() => {
if (this.isSelectMode) {
this.toggleSelection(file.id)
}
})
}
.height(72)
.backgroundColor(this.selectedIds.includes(file.id) ? '#F0F7FF' : '#FFFFFF')
})
}
.width('100%')
.layoutWeight(1)
.divider({ // 设置分割线
strokeWidth: 1,
color: '#E5E5E5',
startMargin: this.isSelectMode ? 72 : 72,
endMargin: 16
})
.multiSelectable(this.isSelectMode) // 启用选择模式
文件列表的关键点:
- 使用
ForEach
遍历文件数据,为每个文件创建一个ListItem
- 在选择模式下显示
Checkbox
,并绑定选择状态和变更事件 - 根据文件是否被选中,设置不同的背景色以提供视觉反馈
- 使用
multiSelectable
属性启用List的多选功能 - 设置分割线样式,并根据是否处于选择模式调整起始边距
4. 底部操作栏实现
if (this.isSelectMode && this.selectedIds.length > 0) {
Row() {
Button('删除')
.width(100)
.height(40)
.backgroundColor('#F44336')
.margin({ right: 16 })
Button('移动')
.width(100)
.height(40)
.backgroundColor('#007DFF')
.margin({ right: 16 })
Button('分享')
.width(100)
.height(40)
.backgroundColor('#4CAF50')
}
.width('100%')
.height(72)
.padding(16)
.justifyContent(FlexAlign.Center)
.backgroundColor('#FFFFFF')
.borderColor('#E5E5E5')
.borderWidth({ top: 1 })
}
底部操作栏仅在选择模式下且有选中项时显示,包含删除、移动和分享三个操作按钮。
六、关键技术点分析
1. 多选功能的实现
多选功能主要通过以下几个方面实现:
- 使用
@State selectedIds: number[]
存储选中项的ID - 通过
toggleSelection
方法管理选中状态 - 使用
List
组件的multiSelectable
属性启用多选功能 - 通过
Checkbox
组件提供选择界面
2. 模式切换的实现
模式切换主要通过@State isSelectMode: boolean
状态变量和toggleSelectMode
方法实现。当模式切换时,UI会相应地变化:
- 标题栏内容变化
- 列表项中显示/隐藏选择框
- 底部操作栏的显示/隐藏
3. 视觉反馈的实现
为了提供良好的用户体验,代码中实现了多种视觉反馈:
- 选中项的背景色变化:
.backgroundColor(this.selectedIds.includes(file.id) ? '#F0F7FF' : '#FFFFFF')
- 已选择项数量的显示:
Text(
已选择 ${this.selectedIds.length} 项)
- 全选/取消全选按钮文本的动态变化:
Button(this.selectedIds.length === this.files.length ? '取消全选' : '全选')
七、代码结构与样式设置
组件部分 | 主要功能 | 样式设置 |
---|---|---|
Column | 整体容器 | 宽高100%,白色背景 |
标题栏Row | 显示标题和操作按钮 | 高56px,左右内边距16px,浅灰背景 |
List | 显示文件列表 | 宽100%,弹性布局权重1,带分割线 |
ListItem | 单个文件项 | 高72px,选中时背景色变化 |
底部Row | 批量操作按钮 | 高72px,内边距16px,居中对齐,顶部边框 |
八、总结
本教程详细讲解了如何在HarmonyOS NEXT中实现一个功能完善的可选择列表 ,通过本教程,你应该能够掌握HarmonyOS NEXT中可选择列表的基本实现方法,并能够应用到自己的项目中。在进阶篇中,我们将探讨如何增强可选择列表的功能,如拖拽排序、搜索过滤、分类显示等高级特性。
- 0回答
- 4粉丝
- 0关注
- 146.[HarmonyOS NEXT 实战案例七 :List系列] 可选择列表进阶篇
- 137.[HarmonyOS NEXT 实战案例七:List系列] 多列列表组件实战:打造精美应用推荐页 基础篇
- 147.[HarmonyOS NEXT 实战案例八 :List系列] 粘性头部列表基础篇
- 155.[HarmonyOS NEXT 实战案例十二 :List系列] 聊天消息列表 - 基础篇
- 135.[HarmonyOS NEXT 实战案例七:List系列] 水平列表组件实战:打造精美图片库 基础篇
- [HarmonyOS NEXT 实战案例六:List系列] 垂直列表组件实战:打造高效联系人列表 基础篇
- 153.[HarmonyOS NEXT 实战案例十一 :List系列] 自定义内容列表 - 基础篇
- 141.[HarmonyOS NEXT 实战案例九:List系列] 分组列表组件实战:打造分类设置菜单 基础篇
- 138.[HarmonyOS NEXT 实战案例七:List系列] 多列列表组件实战:打造精美应用推荐页 进阶篇
- 151.[HarmonyOS NEXT 实战案例十二:List系列] 卡片样式列表组件实战:打造精美电商应用 基础篇
- 136.[HarmonyOS NEXT 实战案例七:List系列] 水平列表组件实战:打造精美图片库 进阶篇
- 148.[HarmonyOS NEXT 实战案例八 :List系列] 粘性头部列表进阶篇
- 156.[HarmonyOS NEXT 实战案例十二 :List系列] 聊天消息列表 - 进阶篇
- 139.[HarmonyOS NEXT 实战案例八:List系列] 滑动操作列表组件实战:打造高效待办事项应用 基础篇
- 143.[HarmonyOS NEXT 实战案例十:List系列] 字母索引列表组件实战:打造高效联系人应用 基础篇