HarmonyOS 鸿蒙Next 如何给一个列表项添加展开的动画?

HarmonyOS 鸿蒙Next 如何给一个列表项添加展开的动画? 主要代码如下

List() {
    ForEach(this.FarmDetailShow, (FarmShow:boolean, index:number) => {
        ListItem() {
            this.FarmListItem(this.FarmList[index].name, this.FarmList[index].fieldId)
        }
        .onClick(() =>{
            this.FarmDetailShow[this.FarmList[index].fieldId] = !this.FarmDetailShow[this.FarmList[index].fieldId]
        })
    })
}
.listDirection(Axis.Vertical)
.divider({
    strokeWidth: 1,
    startMargin: 60,
    endMargin: 10,
    color: '#a1949494' 
})
.scrollBar(BarState.Auto)

其中的FarmListItem()函数如下,

@Builder FarmListItem(name:string,index:number){
    Column(){
        Row() {
            Image($r('app.media.leaf'))
                .width(40)
                .height(40)
                .margin(10)

            Text(name)
                .fontSize(20)
        }

        if(this.FarmDetailShow[index]==true){ //如果被点击,则显示更多内容
            this.DetialShow(this.FarmList[index])
        }
    }
}

我希望实现的功能是在列表的子项被点击后,列表子项展开并显示出更多内容。权威这个需求应该如何实现,指路教程也可以。希望能得到解答,感谢。


更多关于HarmonyOS 鸿蒙Next 如何给一个列表项添加展开的动画?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

@observed+@objectLink,监控item内容,

更多关于HarmonyOS 鸿蒙Next 如何给一个列表项添加展开的动画?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


基本信息

是补全代码?

class FarmListItem {
  name: string = ""
  fieldId: number = 0

  constructor(name, fieldId) {
    this.name = name
    this.fieldId = fieldId
  }
}

@Component
struct test {
  @State FarmDetailShow: Array<boolean> = [true, false, false, true]
  @State FarmList: Array<FarmListItem> = [
    new FarmListItem('张三', 0),
    new FarmListItem('李四', 1),
    new FarmListItem('王五', 2),
    new FarmListItem('张六', 3),
  ]

  build() {
    Column() {
      List() {
        ForEach(this.FarmDetailShow, (FarmShow: boolean, index: number) => {
          ListItem() {
            this.FarmListItem(this.FarmList[index].name, this.FarmList[index].fieldId)
          }
          .onClick(() => {
            this.FarmDetailShow[this.FarmList[index].fieldId] = !this.FarmDetailShow[this.FarmList[index].fieldId]
          })
        })
      }
      .listDirection(Axis.Vertical)
      .divider({
        strokeWidth: 1,
        startMargin: 60,
        endMargin: 10,
        color: '#a1949494' 
      })
      .scrollBar(BarState.Auto)
    }
  }

  @Builder FarmListItem(name: string, index: number) {
    Column() {
      Row() {
        Image($r('app.media.icon'))
          .width(40)
          .height(40)
          .margin(10)

        Text(name)
          .fontSize(20)
      }

      if (this.FarmDetailShow[index] == true) { //如果被点击,则显示更多内容
        this.DetialShow(this.FarmList[index])
      }
    }
  }

  @Builder
  DetialShow(mFarmListItem: FarmListItem) {
    Column() {
      Text('显示更多内容:' + JSON.stringify(mFarmListItem))
    }.width('100%')
  }
}

还是优化代码?

class FarmListItem {
  name: string = ""
  fieldId: number = 0
  isSelect: boolean = false

  constructor(name, fieldId, isSelect) {
    this.name = name
    this.fieldId = fieldId
    this.isSelect = isSelect
  }
}

@Component
struct test {
  @State FarmList: Array<FarmListItem> = [
    new FarmListItem('张三', 0, true),
    new FarmListItem('李四', 1, false),
    new FarmListItem('王五', 2, false),
    new FarmListItem('张六', 3, true),
  ]

  build() {
    Column() {
      List() {
        ForEach(this.FarmList, (FarmList: FarmListItem, index: number) => {
          ListItem() {
            this.FarmListItem(FarmList)
          }
          .onClick(() => {
            FarmList.isSelect = !FarmList.isSelect
            this.FarmList[index] = new FarmListItem(FarmList.name, FarmList.fieldId, FarmList.isSelect)
          })
        })
      }
      .listDirection(Axis.Vertical)
      .divider({
        strokeWidth: 1,
        startMargin: 60,
        endMargin: 10,
        color: '#a1949494' 
      })
      .scrollBar(BarState.Auto)
    }
  }

  @Builder FarmListItem(mFarmListItem: FarmListItem) {
    Column() {
      Row() {
        Image($r('app.media.icon'))
          .width(40)
          .height(40)
          .margin(10)

        Text(mFarmListItem.name)
          .fontSize(20)
      }

      if (mFarmListItem.isSelect) { //如果被点击,则显示更多内容
        this.DetialShow(mFarmListItem)
      }
    }
  }

  @Builder
  DetialShow(mFarmListItem: FarmListItem) {
    Column() {
      Text('显示更多内容:' + JSON.stringify(mFarmListItem))
    }.width('100%')
  }
}

在HarmonyOS中,给列表项添加展开动画可以通过使用Animator组件来实现。首先,你需要在布局文件中定义列表项的结构,确保有需要展开的部分。然后,在代码中使用Animator来定义动画效果。

例如,假设你有一个ListContainer,每个列表项包含一个Text和一个ExpandableLayout。你可以在点击列表项时触发动画。

  1. 定义布局
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:width="match_parent"
    ohos:height="wrap_content">
    <Text
        ohos:id="$+id/text_item"
        ohos:width="match_parent"
        ohos:height="wrap_content"
        ohos:text="Item"/>
    <ExpandableLayout
        ohos:id="$+id/expandable_layout"
        ohos:width="match_parent"
        ohos:height="0"
        ohos:visibility="invisible">
        <!-- 展开的内容 -->
    </ExpandableLayout>
</DirectionalLayout>
  1. 实现动画
Component container = findComponentById(ResourceTable.Id_list_container);
Component expandableLayout = findComponentById(ResourceTable.Id_expandable_layout);

AnimatorProperty animator = new AnimatorProperty();
animator.setDuration(300); // 动画持续时间
animator.setCurveType(Animator.CurveType.EASE_IN_OUT); // 动画曲线
animator.setFloatValue("height", 0, 200); // 从0到200的高度变化

container.setClickedListener(component -> {
    if (expandableLayout.getVisibility() == Component.INVISIBLE) {
        expandableLayout.setVisibility(Component.VISIBLE);
        animator.setTarget(expandableLayout);
        animator.start();
    } else {
        animator.reverse();
    }
});

通过这种方式,你可以在列表项点击时触发展开或收起动画。

在HarmonyOS鸿蒙Next中,可以通过AnimatorTransform组件实现列表项的展开动画。首先,使用Animator定义动画属性,如scaletranslate,然后将其应用到列表项的Transform属性上。通过设置动画的起始值和结束值,以及持续时间,即可实现展开效果。例如,使用scaleY从0到1,配合easeInOut缓动函数,实现平滑展开。

回到顶部