鸿蒙Harmony(八)ArkUI--状态管理器之@State

news/2024/7/21 10:16:19 标签: harmonyos, 华为

状态管理

在声明式UI中,是以状态驱动视图更新
状态:指驱动视图更新的数据(被装饰器标记的变量)

  • @State
  • @Prop 和 @Link
  • @Provide和 @Consume

@State

  • @State装饰器标记的变量必须初始化,不能为空值
  • @State支持Object 、class、string、number、boolean、enum 类型以及这些类型的数组
  • 嵌套类型以及数组中的对象属性无法触发视图更新
    无法触发视图更新的代码示例如下:

嵌套类型无法刷新视图

// 嵌套类型
class Person{
   name:string
   age:number
   friend:Person

  constructor(name:string,age:number,friend?:Person) {
    this.name=name
    this.age=age
    this.friend=friend
  }
}

@Entry
@Component
struct Index {
  @State xiaoming: Person = new Person('xiaoming',13)
  @State xiaohong: Person = new Person('xiaohong',14,new Person("lilei",14))

  build() {
    Row() {
      Column() {
        Text(this.xiaoming.name+"的年龄"+this.xiaoming.age)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .onClick(()=>{
            // 会刷新ui
            this.xiaoming.age++
          })

        Text(this.xiaohong.name+"的朋友的年龄"+this.xiaohong.friend.age)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .onClick(()=>{
            // 嵌套类型,不会刷新ui
            this.xiaohong.friend.age++
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

数组中的对象属性无法触发视图更新

class Person {
  name: string
  age: number
  friend: Person

  constructor(name: string, age: number, friend?: Person) {
    this.name = name
    this.age = age
    this.friend = friend
  }
}

@Entry
@Component
struct Index {
  @State xiaoming: Person = new Person('xiaoming', 13)
  @State friendList: Person[] = [
    new Person("lilei", 14),
    new Person("lilei2", 15)
  ]

  build() {
    Row() {
      Column() {
        Text("朋友列表")
          .fontSize(40)
          .fontWeight(FontWeight.Bold)
        Button("添加朋友")
          .onClick(() => {
            // 点击会增加
            let friendIndex = this.friendList.length
            this.friendList.push(new Person("lilei" + friendIndex, 20))
          })
        ForEach(this.friendList, (item, index) => {
          Row({space:10}) {
            Text(item.name + "的年龄" + item.age)
              .fontSize(20)
              .fontWeight(FontWeight.Bold)
              .onClick(() => {
                // 点击不会发生年龄变更
                item.age++
              })
            Button("删除朋友")
              .onClick(() => {
                // 点击会删除当前项
                this.friendList.splice(index, 1)
              })
          }.width('100%').justifyContent(FlexAlign.SpaceAround)
          .margin({bottom:10,left:10,right:10})
          .borderRadius(15)
          .padding(10)
          .backgroundColor('#cccccc')

        })

      }
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Start)
    }
    .height('100%')
  }
}

应用示例

在这里插入图片描述

涉及内容:
基础组件:Progress CheckBox
容器组件:Stack List

class Task {
  static id: number = 1
  name: string = '任务' + Task.id++
  isDone: boolean = false
}

@Extend(Text) function finishedTask() {
  .decoration({ type: TextDecorationType.LineThrough })
  .fontColor('#B1B2B1')
}

@Entry
@Component
struct TaskPage {
  // 总任务数量
  @State totalTask: number = 0
  @State finishTask: number = 0
  @State taskList: Array<Task> = []

  build() {
    Column() {
      // 1.顶部任务统计部分
      this.TaskProgressView()
      // 2.新增任务
      Button("新增任务").onClick(() => {
        this.taskList.push(new Task())
        this.totalTask = this.taskList.length
      }).width("60%")
        .margin({ top: 10 })
      // 3.任务列表
      List() {
        ForEach(this.taskList, (item, index) => {
          ListItem() {
            this.TaskItemView(item)
          }.swipeAction({ end: this.getDeleteButton(index) })// 向左滑动,出现删除按钮
        })
      }.layoutWeight(1) // 高度权重
      .width('100%')
      .alignListItem(ListItemAlign.Center)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#eeeeee')
    .justifyContent(FlexAlign.Start)
  }

  @Builder TaskProgressView() {
    Row() {
      Text("任务进度:")
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ right: 40 })
      Stack() {
        Progress({ value: this.finishTask, type: ProgressType.Ring, total: this.totalTask }).width(120)
        Text(this.finishTask + "/" + this.totalTask)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
      }
    }.commonCardStyle()
    .height(200)
    .padding({ left: 20, right: 20 })
    .justifyContent(FlexAlign.Center)
  }

  @Builder TaskItemView(task: Task) {
    Row() {
      // 这里不生效,原因:state 数组对象嵌套不刷新视图
      if (task.isDone) {
        Text(task.name)
          .fontSize(15)
          .fontWeight(FontWeight.Bold)
          .margin({ right: 40 })
          .finishedTask()
      } else {
        Text(task.name)
          .fontSize(15)
          .fontWeight(FontWeight.Bold)
          .margin({ right: 40 })
      }
      Checkbox()
        .select(task.isDone).onChange((isChecked) => {
        task.isDone = isChecked
        this.finishTask = this.taskList.filter(item => item.isDone).length
      })
    }.commonCardStyle()
    .height(100)
    .padding({ left: 20, right: 20 })
    .justifyContent(FlexAlign.SpaceBetween)
  }

  @Builder getDeleteButton(index: number) {
    Button({ type: ButtonType.Circle }) {
      Image($r('app.media.del'))
    }
    .onClick(() => {
      this.taskList.splice(index, 1)
      this.finishTask = this.taskList.filter(item => item.isDone).length
      this.totalTask = this.taskList.length
    })
    .width(50)
    .height(50)
    .padding(10)
    .margin({ right: 5 })
    .backgroundColor('#ffffff')
  }

  @Styles commonCardStyle(){
    .width('95%')
    .margin({ left: 10, right: 10, top: 10 })
    .borderRadius(20)
    .backgroundColor('#ffffff')
    .shadow({ radius: 6, color: '#1f000000', offsetX: 2, offsetY: 4 })
  }
}

@Prop 和 @Link

@Provide和 @Consume

@Observerd 和 ObjectLink


http://www.niftyadmin.cn/n/5289571.html

相关文章

【python与机器学习3】感知机和门电路:与门,或门,非门等

目录 1 电子和程序里的与门&#xff0c;非门&#xff0c;或门&#xff0c;与非门 &#xff0c;或非门&#xff0c;异或门 1.1 基础电路 1.2 所有的电路情况 1.3 电路的符号 1.4 各种电路对应的实际电路图 2 各种具体的电路 2.1 与门&#xff08;and gate&#xff09; 2…

Java 8中Collection接口的所有方法举例讲解

Java 8中Collection接口的所有方法举例讲解 一、接口中的方法概览 public interface Collection<E> extends Iterable<E> {int size();boolean isEmpty();boolean contains(Object o);Iterator<E> iterator();Object[] toArray();<T> T[] toArray(T[…

匈牙利算法总结

知识概览 匈牙利算法可以以较快的时间返回二分图的最大匹配数。匈牙利算法的时间复杂度是O(nm)&#xff0c;实际运行时间一般远小于O(nm)&#xff0c;可能是线性的也说不定。因为每次匹配时&#xff0c;比较几次就能匹配了。 例题展示 题目链接 861. 二分图的最大匹配 - AcWi…

软文投放注意事项,媒介盒子分享

软文营销已经成为企业进行品牌推广的新阵地&#xff0c;但是对于软文投放平台的平台规则、投放技巧、流量奖励机制等各种问题的不了解&#xff0c;产生了不少品牌在投放上的误区&#xff0c;导致营销策略失败&#xff0c;今天媒介盒子就来和大家聊聊软文投放的注意事项&#xf…

老用户可买:腾讯云轻量应用服务器2核2G4M带宽118元一年,3年540元

它急了&#xff0c;腾讯云急了&#xff0c;继阿里云推出99元新老用户同享的云服务器后&#xff0c;腾讯云轻量应用服务器2核2G4M配置也支持新老用户同享了&#xff0c;一年118元&#xff0c;3年540元&#xff0c;老用户也能买&#xff0c;50GB SSD系统盘&#xff0c;300GB 月流…

C# Winform教程(一):MD5加密

1、介绍 在C#中&#xff0c;MD5&#xff08;Message Digest Algorithm 5&#xff09;是一种常用的哈希函数&#xff0c;用于将任意长度的数据转换为固定长度的哈希值&#xff08;通常是128位&#xff09;。MD5广泛用于校验数据完整性、密码存储等领域。 2、示例 创建MD5加密…

Deep de Finetti: Recovering Topic Distributions from Large Language Models

Authors: Liyi Zhang ; R. Thomas McCoy ; Theodore R. Sumers ; Jian-Qiao Zhu ; Thomas L. Griffiths Q: 这篇论文试图解决什么问题&#xff1f; A: 这篇论文探讨大型语言模型&#xff08;LLMs&#xff09;如何捕捉文档的主题结构。尽管LLMs是在下一个词预测任务上进行训练的…

不浪费时间,昂首资本1分钟如何快速学习MT4价差

不要浪费时间在手工计算上&#xff0c;昂首资本解释一下如何快速学习MT4价差&#xff0c;。 想要在MT4中输入交易时&#xff0c;需要在交易窗口中设置未来交易的参数。在同一个窗口中&#xff0c;可以看到卖价和买价。如果在上面的例子中比较这两个价格&#xff0c;就会发现两…