参考简版demo:@Observed class Task { static id: number = 1 name: string = `任务${Task.id++}` finished: boolean = false } class StatInfo { totalTask: number = 0 finishTask: number = 0 } @Styles function card() { .width('95%') .padding(20) .backgroundColor(Color.White) .borderRadius(15) .shadow({ radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4 }) } @Extend(Text) function finishTask() { .decoration({ type: TextDecorationType.LineThrough, color: '#B1B2B1' }) .fontColor('#B1B2B1') } @Component struct TaskStatistics { @Consume stat: StatInfo build() { Row() { Text('任务:') .fontSize(30) .fontWeight(FontWeight.Bold) Stack() { Progress({ value: this.stat.finishTask, total: this.stat.totalTask, type: ProgressType.Ring }) .width(100) Row() { Text(this.stat.finishTask.toString()) .fontSize(24) .fontColor('#36D') Text(' / ' + this.stat.totalTask.toString()) .fontSize(24) } } } .card() .margin({ top: 5, bottom: 10 }) .justifyContent(FlexAlign.SpaceEvenly) } } @Component struct TaskList { @Consume stat: StatInfo @State tasks: Task[] = [] handleTaskChange: (res: string) => void = (res) => { console.log(res) this.stat.totalTask = this.tasks.length this.stat.finishTask = this.tasks.filter(item => item.finished).length } build() { Column() { Button('新增') .width(200) .margin({ bottom: 10 }) .onClick(() => { this.tasks.push(new Task()) this.handleTaskChange('2') }) List({ space: 10 }) { ForEach(this.tasks, (task: Task, index) => { ListItem() { TaskListItem({ item: task, onTaskChange: this.handleTaskChange }) } .swipeAction({ end: this.DeleteButton(index) }) }) } } } @Builder DeleteButton(index: number) { Button() { Image('') .backgroundColor(Color.Red) .width(20) .aspectRatio(1) } .width(40) .height(40) .type(ButtonType.Circle) .backgroundColor(Color.Red) .margin(5) .onClick(() => { this.tasks.splice(index,1) this.handleTaskChange('删除') }) } } @Component struct TaskListItem { @ObjectLink item: Task onTaskChange: (e: string) => void = () => { } build() { Row() { if (this.item.finished) { Text(this.item.name) .finishTask() } else { Text(this.item.name) } Checkbox() .shape(CheckBoxShape.ROUNDED_SQUARE) .select(this.item.finished) .onChange((val) => { this.item.finished = val this.onTaskChange(val? '选中':'未选中') }) } .card() .justifyContent(FlexAlign.SpaceBetween) } } @Entry @Component struct TaskListPage { @Provide stat: StatInfo = new StatInfo() build() { Column({ space: 10 }) { Text('列表') .fontSize(20) .fontWeight(FontWeight.Bold) .width('100%') .height(56) .padding({left:20}) TaskStatistics() TaskList() } .width('100%') .height('100%') .backgroundColor('#F1F2F3') } }
参考简版demo: