HarmonyOS鸿蒙Next中当我删除 list 中的某一条数据时 UI上如何实现一个往上顶的动画?

HarmonyOS鸿蒙Next中当我删除 list 中的某一条数据时 UI上如何实现一个往上顶的动画?

List 的数据是来自 ObservedV2 装饰器

@ObservedV2
export class RecruitmentTabUIState {
  @Trace list: LazyDataSource<IRecruitmentListViewType> = new LazyDataSource()
}

当我删除 list 中的某一条数据时 UI 上如何实现一个往上顶的动画?

4 回复

删除补位动画可参考以下demo:

import { LazyDataSource } from '../model/LazyDataSource'

@Observed
export class Item {
  constructor(data: string
  ) {
    this.data = data
  }

  public data: string
  public offsetY: number = 0
  public scale: number = 1
  public opacity: number = 1
}

@Extend(Button)
function circleStyle(background: ResourceColor) {
  .type(ButtonType.Circle)
  .backgroundColor(background)
}

@Component
export struct CardItem {
  @ObjectLink item: Item

  build() {
    Row() {
      Text(this.item.data)
        .fontSize(16)
        .width("100%")
        .height("100%")
        .textAlign(TextAlign.Center)
        .borderRadius(12)
    }
    .translate({ y: this.item.offsetY })
    .borderRadius(12)
    .height(108)
    .justifyContent(FlexAlign.Center)
    .width("100%")
    .backgroundColor("#fff")
  }
}

@Entry
@Component
export struct ListPinAnimation {
  @State dataSource: LazyDataSource<Item> = new LazyDataSource()
  @State CurrentIndex: string = 'undefined'
  private scrollerForList: Scroller = new Scroller()
  @State EndOffset: number = 0

  @Builder
  renderSwipeAction(item: Item) {
    Row({ space: 12 }) {
      Stack().flexGrow(6)
      Button().circleStyle("rgb(63, 196, 63)")
      Stack().flexGrow(6)
      Button().circleStyle("rgb(0, 157, 227)")
      Stack().flexGrow(6)
      Button().circleStyle("rgb(239, 29, 31)").onClick(() => {
        this.CurrentIndex = item.data
        const index = this.dataSource.indexOf(item)
        this.EndOffset = 0
        animateTo({ duration: 0 }, () => {
          this.dataSource.deleteItem(item)
        })
        for (let i = 0; i < this.dataSource.totalCount(); ++i) {
          const element = this.dataSource.getData(i)
          if (i < index) {
            element.offsetY = this.EndOffset
          } else {
            element.offsetY = 120 + this.EndOffset
          }
        }
        for (let i = 0; i < this.dataSource.totalCount(); ++i) {
          const element = this.dataSource.getData(i)
          animateTo({
            curve: Curve.Friction,
            duration: 350,
            delay: Math.abs(index - i) * 16.67,
          }, () => {
            element.offsetY = 0
          })
        }
      })
      Stack().flexGrow(1)
    }.padding(12)
  }

  build() {
    Column() {
      List({ space: 12, scroller: this.scrollerForList }) {
        LazyForEach(this.dataSource, (item: Item) => {
          ListItem() {
            CardItem({ item: item })
          }
          .transition(
            // 只需要删除动效,所以使用不对称的过渡效果
            TransitionEffect.asymmetric(
              // 入场动效:无
              TransitionEffect.IDENTITY,
              // 退场动效:尺寸缩放变化+透明度变化
              TransitionEffect.scale({ x: 0.75, y: 0.75 })
                .animation({ curve: Curve.Friction, duration: 300 })
                .combine(
                  TransitionEffect.OPACITY.animation({ curve: Curve.Sharp, duration: 300 })
                )
            )
          )
          .clip(false)
          .zIndex(this.CurrentIndex == item.data ? 1 : 2)
          .swipeAction({ end: this.renderSwipeAction(item) })
          .width("100%")
        }, (item: Item) => item.data)
      }
      .height("100%")
      .scrollBar(BarState.Off)
      .onScroll((scrollOffset: number, scrollState: ScrollState) => {
        console.log(`${scrollOffset}`)
        this.EndOffset = scrollOffset
      })
    }
    .backgroundColor("#f1f2f3")
    .height("100%")
    .padding(24)
    .width("100%")
  }

  aboutToAppear() {
    for (let i = 0; i < 50; i++) {
      this.dataSource.pushItem(new Item(i.toString()))
    }
  }
}

更多关于HarmonyOS鸿蒙Next中当我删除 list 中的某一条数据时 UI上如何实现一个往上顶的动画?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


有demo吗v2的,

在HarmonyOS鸿蒙Next中,当你删除列表中的某一条数据时,可以通过使用List组件的delete方法和animateTo方法来实现一个往上顶的动画效果。

首先,你需要获取到List组件的引用,然后调用delete方法删除指定项。接着,使用animateTo方法来定义动画效果,设置translateY属性来实现项的上移动画。

示例代码如下:

import { List, ListItem, animateTo } from '@ohos.arkui';

// 假设你已经有一个List组件的引用
let list = ...;

// 删除指定项
list.delete(index);

// 使用animateTo方法定义动画
animateTo({
  duration: 300, // 动画持续时间
  curve: 'easeInOut', // 动画曲线
  onFrame: (progress) => {
    // 计算每一帧的translateY值
    let translateY = -progress * itemHeight;
    // 应用动画到指定项
    list.getItem(index).style.transform = \`translateY(\${translateY}px)\`;
  },
  onFinish: () => {
    // 动画完成后的操作
  }
});

在这个示例中,itemHeight是列表项的高度,index是要删除的项的索引。通过animateTo方法,你可以控制动画的持续时间和曲线,并在每一帧中更新项的translateY值,从而实现往上顶的动画效果。

注意:具体的实现可能会根据你的实际需求和项目结构有所不同。

在HarmonyOS鸿蒙Next中,你可以使用ListContainerremoveChildAt方法删除指定位置的数据项,并通过Animator实现动画效果。首先,删除数据项后,使用Animator对剩余项进行位移动画,设置translateY属性,使其向上移动填补空位。具体步骤包括:

  1. 删除数据项;
  2. 遍历剩余项,计算目标位置;
  3. 为每个项创建并启动位移动画,设置合适的持续时间和插值器以实现平滑过渡。
回到顶部