HarmonyOS 鸿蒙Next List 删除数据源UI更新的同时 如何设置删除动画效果

发布于 1周前 作者 itying888 来自 鸿蒙OS

HarmonyOS 鸿蒙Next List 删除数据源UI更新的同时 如何设置删除动画效果

现在官网关于仓颉UI的介绍和功能都很少,后续会开放相应demo和交互示例么?比如仓颉如何和native交互方面的示例?

有的话麻烦提供下示例代码

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

index.ets

深色代码主题
复制
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(<span class="hljs-subst">${scrollOffset}</span>)

        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()))

    }

  }

}

```

LazyDataSource.ets

```

export class LazyDataSource<T> implements IDataSource {

  private elements: T[]

  private listeners: Set<DataChangeListener>

  constructor(elements: T[] = []) {

    this.elements = elements

    this.listeners = new Set()

  }

  public totalCount(): number {

    return this.elements.length

  }

  public getData(index: number): T {

    return this.elements[index]

  }

  public indexOf(item: T): number {

    return this.elements.indexOf(item)

  }

  public pinItem(item: T, index: number): void {

    this.elements.splice(index, 1)

    this.elements.unshift(item)

    this.listeners.forEach(listener => listener.onDataReloaded())

  }

  public addItem(item: T) {

    this.elements.unshift(item)

    this.listeners.forEach(listener => listener.onDataAdd(0))

  }

  public pushItem(item: T) {

    this.elements.push(item)

    this.listeners.forEach(listener => listener.onDataAdd(this.elements.length - 1))

  }

  public insertItem(item: T, index: number) {

    this.elements.splice(index, 0, item)

    this.listeners.forEach(listener => listener.onDataAdd(index))

  }

  public deleteItem(item: T): void {

    const index = this.elements.indexOf(item)

    if (index < 0) {

      return

    }

    this.elements.splice(index, 1)

    this.listeners.forEach(listener => listener.onDataDelete(index))

  }

  public deleteItemByIndex(index: number): void {

    this.elements.splice(index, 1)

    this.listeners.forEach(listener => listener.onDataDelete(index))

  }

  public registerDataChangeListener(listener: DataChangeListener): void {

    this.listeners.add(listener)

  }

  public unregisterDataChangeListener(listener: DataChangeListener): void {

    this.listeners.delete(listener)

  }

}

更多关于HarmonyOS 鸿蒙Next List 删除数据源UI更新的同时 如何设置删除动画效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙系统中,为Next List组件设置删除数据源后的UI更新及删除动画效果,可以通过以下步骤实现:

  1. 数据源更新

    • 当你从数据源中移除某个项目时,确保数据源列表(例如ArrayList)已正确更新。
    • 调用适配器的notifyDataSetChanged()notifyItemRemoved(int position)方法来通知列表更新。
  2. 动画效果设置

    • 在你的RecyclerView.Adapter中,重写onBindViewHolder方法,并在其中设置动画。
    • 可以通过ViewHolderitemView获取到要动画的视图,然后使用AnimationUtils.loadAnimation加载动画资源。
    • 在删除数据后,立即对相应的视图应用动画,例如淡出或滑动效果。
  3. 同步UI与动画

    • 确保数据源更新和动画执行是同步进行的,即在数据源更新后紧接着启动动画。
    • 可以通过在notifyItemRemoved之后立即启动动画来实现。

示例代码片段(伪代码):

// 假设你有一个名为adapter的RecyclerView.Adapter实例
dataSource.remove(position);
adapter.notifyItemRemoved(position);

View viewToRemove = recyclerView.findViewHolderForAdapterPosition(position).itemView;
Animation animation = AnimationUtils.loadAnimation(context, R.anim.slide_out_right);
viewToRemove.startAnimation(animation);

注意:以上代码仅为示例,实际实现需根据具体需求调整。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部