基于@State来创建一个任务管理的案例。
//任务类
class Task {
static id: number = 1
name:string = '任务名称'+Task.id++
finished:boolean = false
}
//公共卡片样式
@Styles function card() {
.width('90%')
.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({radius:6,color:'#1F00000',offsetX:2,offsetY:4})
}
//扩展Text的样式,完成效果
@Extend(Text) function successd() {
.decoration({type: TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
@Entry
@Component
struct ProgressTask {
@State totalTasks: number = 0
@State finishTasks:number = 0
@State tasks: Task[] = []
handleTaskNumber() {
this.totalTasks = this.tasks.length
this.finishTasks = this.tasks.filter(item =>
item.finished
).length
console.log('完成任务数'+this.finishTasks)
}
build() {
Column() {
//进度卡片
Row() {
Text('任务进度:')
.fontWeight(FontWeight.Bold)
.fontSize(30)
.layoutWeight(1)
//Stack组件可以让内部的组件堆叠
Stack() {
//Progress进度条
Progress({value:this.finishTasks,total:this.totalTasks,type:ProgressType.Ring})
.width(100)
Row() {
Text(this.finishTasks.toString())
.fontSize(24)
.fontColor('#36D')
Text(' / '+this.totalTasks.toString())
.fontSize(24)
}
}
}
.card()
.height(150)
.margin({top:20,bottom:10})
.justifyContent(FlexAlign.SpaceEvenly)
//添加按钮
Button('新增任务')
.width(200)
.height(35)
.onClick(() => {
this.tasks.push(new Task())
this.handleTaskNumber()
})
.margin({bottom:20})
//任务列表
List({space:10}){
ForEach(this.tasks,(task:Task,index) => {
ListItem() {
Row(){
Text(task.name)
.fontSize(20)
Checkbox()
.select(task.finished)
.onChange(value => {
task.finished = value
console.log('任务状态'+value+'')
this.handleTaskNumber()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end:this.deleteButton(index)})
},item => ''+item.name)
}
.width('100%')
.alignListItem(ListItemAlign.Center)
.layoutWeight(1)
}
.width('100%')
.height('100%')
}
//ListItem左滑返回视图
@Builder deleteButton(index:number) {
Button('➖')
.fontColor(Color.White)
.backgroundColor(Color.Red)
.width(40)
.height(40)
.type(ButtonType.Circle)
.margin({left:5})
.onClick(() => {
this.tasks.splice(index,1)
this.handleTaskNumber()
})
}
}
开发过程中的新知识点
1、Stack组件
该组件支持内部的组件堆叠
Stack() {
Text('任务进度1:')
.fontWeight(FontWeight.Bold)
.fontSize(30)
.layoutWeight(1)
Text('任务进度2:')
.fontWeight(FontWeight.Bold)
.fontSize(30)
.layoutWeight(1)
}
2、数组的添加删除元素方式
//插入一个元素
this.tasks.push(Element)
//删除从index起length个元素
this.tasks.splice(index,length)
3、勾选框CheckBox组件
Checkbox()
//选中状态
.select(task.finished)
.onChange(value => {
//状态改变回调
})
4、Progress组件
//value是当前进度,total总值,type样式
Progress({value:this.finishTasks,total:this.totalTasks,type:ProgressType.Ring})
5、给ListItem添加左滑事件
ListItem() {
Row(){
Text(task.name)
.fontSize(20)
}
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end:this.deleteButton(index)})
},item => ''+item.name)
6、遇到的坑
在做的过程中,最开始Task的name,id等都是一样的,然后,导致处理ListItem各种异常,应该是复用刷新机制的问题。后来处理成name不一样,并且将name设置为ListItem的keyGenerator。这个字段我理解为原生开发的复用ID。因为每个task的id一样导致ListItem没有刷新。这个待后期学习验证。