ArkTS的剩余状态管理基础部分及渲染控制

上篇回顾 ArkTS的应用级变量的状态管理学习

本篇内容 ArkTS的剩余状态管理基础部分及渲染控制

一、知识储备

1. @Watch状态变量变化的监听装饰器

  • 观察到绑定的状态变量发生变化时,触发对应的回调函数
  • 在第一次初始化的时候,@Watch装饰的函数不会被执行,
  • 如果在@Watch装饰的函数内改变了其他的状态变量,也会引起状态变更和@Watch的执行

2. if else 条件判断

    if (this.count > 29) {
      this.total = this.count * 3
    } else if (this.count > 12) {
      this.total = this.count * 2
    } else {
      this.total = this.count * 1
    }

3. switc 条件判断

          switch (refreshStatus) {
            case RefreshStatus.Inactive:
              console.error('Refresh status Inactive is ' + refreshStatus)
              break;
            case RefreshStatus.Drag:
              console.error('Refresh status Drag is ' + refreshStatus)
              this.counter += 1;
              break;
            case RefreshStatus.OverDrag:
              console.error('Refresh status OverDrag is ' + refreshStatus)
              break;
            case RefreshStatus.Refresh:
              console.error('Refresh status Refresh is ' + refreshStatus)
              break;
            case RefreshStatus.Done:
              console.error('Refresh status Done is ' + refreshStatus)
              break;
          }

4. ForEach 循环渲染

        ForEach(this.foodArr, (item: string) => {
          Food({ food: item })
       })

5.LazyForEach

  • 必须在容器组件内使用,仅有List/Grid/Swiper以及WaterFlow组件支持数据懒加载
LazyForEach(
dataSource: IDataSource,             // 需要进行数据迭代的数据源
itemGenerator: (item: any, index: number) => void,  // 子组件生成函数
keyGenerator?: (item: any, index: number) => string // 键值生成函数
): void

二、效果一览

在这里插入图片描述

三、源码分析讲解

@Entry
@Component
struct AppOtherPage {
  @State count: number = 2;
  @State isRefreshing: boolean = false
  @State counter: number = 0;
  @State foodArr: string[] = ['西红柿', '土豆', '苹果', '西瓜']
  private dataSource: MyDataSource = new MyDataSource(); //定义数据源

  aboutToAppear() {
    for (let i = 0; i < 30; i++) {
      this.dataSource.pushData('我是第' + i + '个')
    }
  }

  build() {
    Row() {
      Column() {

        Goods({ count: this.count })
        Text(`页面刷新状态是:${this.isRefreshing}`)
        Refresh({ refreshing: $$this.isRefreshing, offset: 120, friction: 100 }) {
          Text(`正在下拉刷新第${this.counter}次`)
        }
        .onStateChange((refreshStatus: RefreshStatus) => {
          switch (refreshStatus) {
            case RefreshStatus.Inactive:
              console.error('Refresh status Inactive is ' + refreshStatus)
              break;
            case RefreshStatus.Drag:
              console.error('Refresh status Drag is ' + refreshStatus)
              this.counter += 1;
              break;
            case RefreshStatus.OverDrag:
              console.error('Refresh status OverDrag is ' + refreshStatus)
              break;
            case RefreshStatus.Refresh:
              console.error('Refresh status Refresh is ' + refreshStatus)
              break;
            case RefreshStatus.Done:
              console.error('Refresh status Done is ' + refreshStatus)
              break;
          }
        })

        ForEach(this.foodArr, (item: string) => {
          Food({ food: item })
        })

        Button(`商品价格计算${this.count}`)
          .onClick(() => {
            this.count += 5;
          })
          .type(ButtonType.Capsule)

        Button(`添加数据到列表尾部`)
          .onClick(() => {
            this.dataSource.pushData('我是尾部追加的')
          })
          .type(ButtonType.Capsule)
        Button(`添加数据到列表第十位`)
          .onClick(() => {
            this.dataSource.addData(10,'我是手动添加的')
          })
          .type(ButtonType.Capsule)
        List({ space: 3 }) {
          LazyForEach(this.dataSource, (item: string) => {
            ListItem() {
              Row() {
                Food({ food: item })
                  .onAppear(() => {
                    console.error('appear:' + item)
                  })
              }.margin({ left: 10, right: 10, top: 10 })
            }
          }, (item: string) => item)
        }.cachedCount(5)
        .height('100%')
      }
    }

  }
}

@Component
struct Food {
  @State food: string = 'food'

  build() {
    Row() {
      Column() {
        Text(this.food)
          .height('10%')
          .fontSize(44)
          .fontWeight(FontWeight.Bold)
      }
    }
  }
}

@Component
struct Goods {
  @Prop @Watch('calcAmount') count: number;
  @State total: number = 0;

  calcAmount(): void {
    if (this.count > 29) {
      this.total = this.count * 3
    } else if (this.count > 12) {
      this.total = this.count * 2
    } else {
      this.total = this.count * 1
    }
  }

  build() {

    Text(`商品的总价是:${this.total}`)
  }
}

class BasicDataSource implements IDataSource {
  private listenerArr: DataChangeListener [] = [];
  protected listData: string[] = [];

  public totalCount(): number {
    return this.listData.length
  }

  public unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listenerArr.indexOf(listener);
    if (pos > 0) {
      console.info('remove listener')
      this.listenerArr.splice(pos, 1)
    }
  }

  public registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listenerArr.indexOf(listener) < 0) {
      console.info('add listener')
      this.listenerArr.push(listener)
    }
  }

  public getData(index: number): string {
    return this.listData[index];
  }

  notifyDataReload(): void {
    this.listenerArr.forEach(listener => {
      listener.onDataReloaded();
    })
  }

  notifyDataChange(index: number): void {
    this.listenerArr.forEach(listener => {
      listener.onDataChange(index)
    })
  }

  notifyDataAdd(index: number): void {
    this.listenerArr.forEach(listener => {
      listener.onDataAdd(index)
    })
  }

  notifyDataDelete(index: number): void {
    this.listenerArr.forEach(listener => {
      listener.onDataDelete(index)
    })
  }

  notifyDataMove(from: number, to: number): void {
    this.listenerArr.forEach(listener => {
      listener.onDataMove(from, to)
    })
  }
}

class MyDataSource extends BasicDataSource {
  private dataArr: string[] = []

  public totalCount(): number {
    return this.dataArr.length;
  }

  public getData(index: number): string {
    return this.dataArr[index]
  }

  public addData(index: number, data: string): void {
    this.dataArr.splice(index, 0, data)
    this.notifyDataAdd(index)
  }

  public pushData(data: string): void {
    this.dataArr.push(data)
    this.notifyDataAdd(this.dataArr.length - 1)
  }
}
  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值