List列表子组件按照顺序动画展示
=================

#### 问题现象

列表（List）通常会一次性全部展示出来，那么如何实现列表中的子组件能够依照链式先后顺序动画进行展示？

#### 背景知识

组件的某些通用属性变化时，可以通过[animation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-animatorproperty)属性动画实现渐变过渡效果。

#### 解决方案

1.  根据数据源this.data创建List。
    
    if (this.isShow) {
      List() {
        ForEach(this.data, (item: number) \=\> {
          ListItem() {
            CardItem({ index: item });
          }
          .margin(10)
        }, (item: number) \=\> item.toString())
      }
    }
    
2.  创建List的每个子组件CardItem,该组件可以根据其在列表中的索引（index）来计算出一个适当的延迟时间，从而实现一种链式的动画效果，即前一个动画结束之后，下一个动画随即开始。
    
    .animation({
      duration: 500,
      delay: this.index \* 120,
      curve: Curve.EaseOut
    })
    
3.  当CardItem组件首次出现在视图中（即onAppear事件被触发时），将启动该组件的入场动画。
    
    .onAppear(() => {
      this.isAppear = true;
    })
    .onDisAppear(() => {
      this.isAppear = false;
    })
    
4.  完整示例参考如下：
    
    @Component
    struct CardItem {
     _ // 创建List的每个子组件CardItem_
      @Prop index: number;
      @State isAppear: boolean \= false;
      build() {
        Column() {
          Text(\`${this.index}\`).fontColor(Color.Blue).fontSize(24);
        }
        .justifyContent(FlexAlign.Center)
        .alignItems(HorizontalAlign.Center)
        .backgroundColor(Color.Green)
        .height(60)
        .width('100%')
        .opacity(this.isAppear ? 1 : 0)
        .translate({ x: this.isAppear ? 0 : 100 })
        .borderRadius(8)
        _// 增加动画效果_
        .animation({
          duration: 500,
          delay: this.index \* 120,
          curve: Curve.EaseOut
        })
       _ // 组件出现启动组件的入场动画_
        .onAppear(() \=\> {
          this.isAppear \= true;
        })
        .onDisAppear(() \=\> {
          this.isAppear \= false;
        })
      }
    }
    
    @Entry
    @Component
    struct ChainList {
      private data: number\[\] \= \[0, 1, 2, 3, 4, 5\];
      @State isShow: boolean \= false; _// 是否展示List_
      build() {
        Column() {
          Button('show list').onClick(() \=\> {
            this.isShow \= !this.isShow;
          })
        _  // 根据数据源this.data创建List_
          if (this.isShow) {
            List() {
              ForEach(this.data, (item: number) \=\> {
                ListItem() {
                  CardItem({ index: item });
                }
                .margin(10)
              }, (item: number) \=\> item.toString())
            }
          }
        }.justifyContent(FlexAlign.Center).width('100%')
      }
    }
    

#### 总结

属性动画（animation）能够与诸如列表(List)之类的组件相配合，通过调整这些组件的特定属性，如width、height、backgroundColor等，实现一系列动态视觉效果。