课程地址: 黑马程序员HarmonyOS4+NEXT星河版入门到企业级实战教程,一套精通鸿蒙应用开发
(本篇笔记对应课程第 16 节)
P16《15.ArkUI-状态管理-任务统计案例》
1、实现任务进度卡片
怎么让进度条和进度展示文本堆叠展示?需要一个新的布局容器:Stack
2、实现新增任务按钮
3、实现任务列表渲染:
将更新任务总数量与已完成数量的逻辑封装为一个方法,在新增任务与勾选/取消勾选时都调用这个方法:
4、实现左滑显示删除按钮功能:
首先用 List 与 ListItem 改善任务列表:
**要实现左滑显示删除按钮功能,需要 ListItem 的属性 swipeAction 实现:其对应的参数是一个自定义构建函数。**强烈建议这个自定义构建函数定义为局部的,因为删除某一个任务时需要操作任务数组:
实践:
class Task {
static id:number = 1
// 任务名称
name:string = `任务${Task.id++}`
// 任务状态:是否完成
finished:boolean = false
}
@Styles function cardStyle(){
.width('100%')
.height(120)
.padding(10)
.backgroundColor('#fff')
.borderRadius(8)
}
@Entry
@Component
struct Index {
// 总任务数量
@State totalTask:number = 0
// 已完成任务数量
@State finishTask:number = 0
// 任务列表
@State tasks:Task[] = []
handleTaskChange(){
// 更新任务总数量
this.totalTask = this.tasks.length
// 更新已完成任务数量
this.finishTask = this.tasks.filter(item => item.finished).length
}
build() {
Row() {
Column() {
// 1、任务进度卡片
Row(){
Text('任务进度:')
.fontSize(22)
.fontWeight(FontWeight.Bold)
Stack(){
Progress({
value : this.finishTask,
total : this.totalTask,
type : ProgressType.Ring
})
Row(){
Text(this.finishTask.toString())
Text(`/${this.totalTask.toString()}`)
}
}
}
.cardStyle()
.justifyContent(FlexAlign.SpaceEvenly)
// 2、新增任务按钮
Button('新增任务')
.width(200)
.margin({top:20, bottom:20})
.onClick(()=>{
// 新增任务
this.tasks.push(new Task())
// 更新任务总数量
// this.totalTask = this.tasks.length
this.handleTaskChange()
})
// 3、任务列表展示
List(){
ForEach(this.tasks,(item:Task,index)=>{
ListItem(){
Row(){
Text(item.name)
Checkbox()
.select(item.finished)
.onChange(val => {
// 更新任务状态
item.finished = val
// 更新已完成任务数量
// this.finishTask = this.tasks.filter(item => item.finished).length
this.handleTaskChange()
})
}
.cardStyle()
.height(60)
.margin({bottom:10})
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({ end: this.deleteBtn(index)})
})
}
.layoutWeight(1)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Start)
}
.height('100%')
.width('100%')
.padding({top:20,bottom :20, left:10,right:10})
.backgroundColor('#efefef')
}
@Builder deleteBtn(index){
Button(){
Image($r('app.media.icon_delete'))
.width(30)
.fillColor(Color.Red)
}
.width(40)
.height(40)
.type(ButtonType.Circle)
.backgroundColor(Color.Red)
.margin(6)
.onClick(() => {
this.tasks.splice(index,1)
this.handleTaskChange()
})
}
}