黑马任务进度案例详细讲解+代码(鸿蒙开发)

码云仓库地址:https://gitee.com/lin_zixiang/hongmeng-learning.git
在\src\main\ets\pages\TaskManager1.ets该文件下

  1. 效果图
    在这里插入图片描述
  2. 页面入口

页面分为了两部分组件,上部分是任务进度的视图,下部分是新增按钮和任务列表

@Entry
@Component
struct TaskPage {
  @State totalTask: number = 0
  @State finishTask: number = 0

  build() {
    Column({ space: 20 }) {
      //上半部分任务进度组件
      progressView({ totalTask: this.totalTask, finishTask: this.finishTask })
      //下半部分新增任务+任务列表组件。
      progressList({ totalTask: $totalTask, finishTask: $finishTask })
    }
    .width('100%')
    .height('100%')
    .padding({ top: 20 })
    .backgroundColor('#ffeceaea')
  }
}
  1. 任务进度组件
@Component
struct progressView {
  @Prop totalTask: number
  @Prop finishTask: number

  build() {
    Row() {
      Text('任务进度:')
        .fontWeight(FontWeight.Bold)
        .fontSize(30)
      //Stack,实现Text叠在进度条的上方
      Stack() {
        Progress({ value: this.finishTask, type: ProgressType.Ring, total: this.totalTask })
          .width(100)
        Row() {
          Text(this.finishTask + '')
            .fontSize(30)
            .fontColor('#36D')
          Text(' / ' + this.totalTask)
            .fontSize(30)
        }
      }
    }
    .card()
    .justifyContent(FlexAlign.SpaceEvenly)
  }
}
  1. 任务进度列表组件
//任务进度列表组件
@Component
struct progressList {
  @Link totalTask: number
  @Link finishTask: number
  @State task: Task[] = []

  build() {
    Column({ space: 15 }) {
      Button('新增任务')
        .width('50%')
        .onClick(() => {
          this.task.push(new Task()) //id和taskName都是默认值
          this.updateTask()
        })
      //任务列表会超出屏幕,所以用List,可以滑动
      List({ space: 10 }) {
        ForEach(
          this.task,
          (item: Task, index) => {
            ListItem() {
              //提取出任务列表样式,为了实现数组对象可以双向绑定。也就是数组里的对象改变会重新渲染视图
              textElemnet({ item: item, onUpdateTask: this.updateTask.bind(this) }) //bind(this),则方法内的this就指向当前组件
            }
            .swipeAction({ end: this.deleteButton(index) }) //向右滑动时显示构件,并传index用于删除,这个index是数组的下标
          }
        )
      }
      .alignListItem(ListItemAlign.Center) //左右居中
      .width('100%')
      .layoutWeight(1) //List可以往下拖的关键设置,除了前边别的设置的,剩下的都是List的
    }
  }

  //更新已完成和总的数量
  updateTask() {
    this.totalTask = this.task.length //点击新增,总长度需要随着数组长度改变
    this.finishTask = this.task.filter(item => item.isFinish).length //当前完成的值为总的选中的任务,即所有任务先过滤,item.isFinish是返回为true的数据
  }

  //删除按钮
  @Builder deleteButton(index: number) {
    Button() {
      Image($r('app.media.deleteTask'))
        .width(20)
    }
    .width(40)
    .height(40)
    .type(ButtonType.Circle)
    .backgroundColor('#fff50d0d')
    .margin(5)
    .onClick(() => {
      this.task.splice(index, 1)
      this.updateTask()
    })
  }
}

//因为要使数组中的对象成为双向绑定数据,所以要提取出数据
@Component
struct textElemnet {
  @ObjectLink item: Task
  onUpdateTask: () => void //变量,类型是函数

  build() {
    Row() {
      if (this.item.isFinish) {
        Text(this.item.taskName)
          .finishTask()
      } else {
        Text(this.item.taskName)
      }
      Checkbox()
        .select(this.item.isFinish) //复选款选不选中,取决于isFinish
        .onChange((val) => { //val是是否选中的值
          this.item.isFinish = val
          this.onUpdateTask()
        })
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .card()
  }
}
  1. 抽取出来的公共样式或类
//卡片样式
@Styles function card() {
  .width('95%')
  .backgroundColor('#fff')
  .borderRadius(15)
  .padding({ top: 20, bottom: 20, left: 20, right: 20 })
}

//任务完成的样式
@Extend(Text) function finishTask() {
  .decoration({ type: TextDecorationType.LineThrough })
  .fontColor('#B1B2B1')
}

//任务的类
@Observed
class Task {
  static id: number = 0; //公共的,所有此类对象共享
  taskName: string = `任务${++Task.id}` //直接初始化,Task调用
  isFinish: boolean = false
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值