DEV Community

HarmonyOS
HarmonyOS

Posted on

Add sliding gesture listener to Swiper

Read the original article:Add sliding gesture listener to Swiper

Problem Description

When using the Swiper component, how can you detect — after the user lifts their finger — whether the component will move to the next screen or remain on the current screen?

Background Knowledge

onAnimationStart and onAnimationEnd are two important functions in HarmonyOS used for handling animation events. These functions are triggered at the start and end of an animation, respectively, allowing developers to execute custom logic at those points.

The parameters for onAnimationStart include:

The SwiperAnimationEvent object contains:

  • currentOffset
  • targetOffset
  • velocity

By logging or printing these parameters, you can monitor and analyze the swipe gesture.

The methods showNext and showPrevious are used to programmatically go to the next or previous page with animation. The transition duration can be configured using the duration property of the Swiper component

Solution

You can output (log) the index and targetIndex values during the swipe.

  • If index === targetIndex, it means the user did not swipe into a new page when lifting their finger.
  • If the values are different, it indicates the user has swiped into a new page.

Implementation Steps

Follow these steps to implement the behavior:

  1. Create a data source class: Implement the IDataSource interface to provide data for the Swiper component. For example, create a MyDataSource class to store and manage the data items.
  2. Initialize component and data: In the component’s lifecycle method aboutToAppear(), initialize the data source and assign it to the Swiper component.
  3. Construct the Swiper component: Use the Swiper component, and use a LazyForEach loop to render the data items. Each item can be a Text component or a custom component.
  4. Add swipe event listener: Use the onAnimationStart callback to monitor the start of the swipe gesture.
  5. Add control buttons: Use a Row layout to add buttons for showNext and showPrevious, which call swiperController.showNext() and swiperController.showPrevious() respectively, to allow manual page switching.

Code Snippet/ Configuration

class MyDataSource implements IDataSource {
  private list: number[] = []

  constructor(list: number[]) {
    this.list = list
  }

  totalCount(): number {
    return this.list.length
  }

  getData(index: number): number {
    return this.list[index]
  }

  registerDataChangeListener(listener: DataChangeListener): void {
  }

  unregisterDataChangeListener() {
  }
}

@Entry
@Component
struct SwiperExample {
  private swiperController: SwiperController = new SwiperController()
  private data: MyDataSource = new MyDataSource([])
  private currentIndex: number = 4

  aboutToAppear(): void {
    let list: number[] = []
    for (let i = 0; i <= 10; i++) {
      list.push(i);
    }
    this.data = new MyDataSource(list)
  }

  build() {
    Column({ space: 5 }) {
      Swiper(this.swiperController) {
        LazyForEach(this.data, (item: string) => {
          Text(item.toString())
            .width('50%')
            .height(80)
            .margin({ top: 32 })
            .backgroundColor(0xAFEEEE)
            .textAlign(TextAlign.Center)
            .fontSize(30)
        }, (item: string) => item)
      }
      .index(this.currentIndex) // Set the currently displayed index
      .loop(false) // Set whether to loop display. false means no loop
      // Listen for changes in the current index and update currentIndex when sliding to a new page
      .onChange((index: number) => {
        this.currentIndex = index
      })
      .onAnimationStart((index: number, targetIndex: number, extraInfo: SwiperAnimationEvent) => {
        console.info('index: ' + index)
        console.info('targetIndex: ' + targetIndex)
        console.info('current offset: ' + extraInfo.currentOffset)
        console.info('target offset: ' + extraInfo.targetOffset)
        console.info('velocity: ' + extraInfo.velocity)
      }) // The core is this code

      Row({ space: 12 }) {
        Button('showNext')
          .onClick(() => {
            this.swiperController.showNext()
          }).fontSize(12)
        Button('showPrevious')
          .onClick(() => {
            this.swiperController.showPrevious()
          }).fontSize(12)
      }.margin(5)
    }.width('100%')
    .margin({ top: 5 })
  }
}Copy codeCopy code
Enter fullscreen mode Exit fullscreen mode

The preview effect is as follows:

3.png

The preview effect is as follows:

4.png

The output result is consistent with the effect diagram.
In addition, currentOffset, targetOffset, and velocity respectively output the displacement of the Swiper's current display element in the main axis direction relative to the Swiper's starting position, the displacement of the Swiper animation target element in the main axis direction relative to the Swiper's starting position, and the hand-off speed when the Swiper hand-off animation starts. These data can monitor gestures more specifically.

Related Documents or Links

https://developer.huawei.com/consumer/en/doc/harmonyos-references/ts-container-swiper#swiperanimationevent10

Written by Hatice Akyel

Top comments (0)