DEV Community

HarmonyOS
HarmonyOS

Posted on

LazyForEach implements item deletion animation effect

Read the original article:LazyForEach implements item deletion animation effect

Problem Description

For data sources managed by LazyForEach and displayed using a List, how can you implement an animation that removes items from right to left when a data item is deleted from the data source?

Background Knowledge

  • Component-level transitions can be used to achieve animation effects when inserting or deleting child components within a container component.
  • LazyForEach iterates over data from the provided data source on demand. The data source type is IDataSource, and developers need to implement the relevant interfaces.

Solution

CustomDataSource is a data source implemented to inherit from IDataSource, with relevant interfaces overridden.
In the AnimatedPage, the ListItem implements a left-to-right deletion animation. When the Button is clicked to delete data from CustomDataSource, the List will display the deletion animation.

export class CustomDataSource implements IDataSource {
  data: string[] = ['Item 0', 'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'];
  private listeners: DataChangeListener[] = [];

  // Total number of data obtained
  totalCount(): number {
    return this.data.length;
  }

  // Retrieve data for a specified index
  getData(index: number): string {
    return this.data[index];
  }

  // Delete Data Method
  deleteData(index: number) {
    if (index >= 0 && index < this.data.length) {
      this.data.splice(index, 1);
      this.notifyDataDelete(index);
    }
  }

  // Registration Data Change Listening
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      this.listeners.push(listener);
    }
  }

  // Deregistration Data Change Listening
  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      this.listeners.splice(pos, 1);
    }
  }

  // Notification of Data Deletion
  private notifyDataDelete(index: number) {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index);
    });
  }
}
Enter fullscreen mode Exit fullscreen mode
import { CustomDataSource } from './CustomDataSource';

@Entry
@Component
struct AnimatedPage {
  private dataSource = new CustomDataSource();

  build() {
    Column() {
      Button('delete item')
        .onClick(() => this.deleteItem(0))
        .margin('16vp')
      List({ space: 10 }) {
        LazyForEach(this.dataSource, (item: string, index: number) => {
          ListItem() {
            Text(item).fontSize(20).height(30)
          }
          .width('100%')
          .height('30vp')
          .backgroundColor('#0A59F7')
          .transition(TransitionEffect.opacity(0.5) // Delete animation implementation
            .combine(TransitionEffect.translate({ x: '-200vp' })))
        }, (item: string) => item)
      }
      .padding(16)
    }
  }

  deleteItem(index: number) {
    this.getUIContext().animateTo({ duration: 500 }, () => {
      this.dataSource.deleteData(index);
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Verification Result

kbs--ccf6b57135ed4e94bdd6641ec63b920e-286ff.png

Written by Mehmet Emir Ucar

Top comments (0)