DEV Community

HarmonyOS
HarmonyOS

Posted on

onTouch Global Swipe Event Listener

Read the original article:onTouch Global Swipe Event Listener

Requirement Description

How to globally listen for swipe events to control the visibility of the purple subcomponent and achieve the function shown below?

cke_1051.gif

Background Knowledge

onTouch: This callback is triggered when a finger touch occurs. When the left mouse button is pressed, the event is also converted into a touch event and triggers this callback.

Implementation Steps

Create a purple stack component and set the visibility property. Determine the visibility of the component by checking the flag isDirectShowPlayPanel.

Code example:

if (this.isShowPlayPanel) {
  Stack() {

  }
  .width('100%')
  .height(80)
  .hitTestBehavior(HitTestMode.None)
  .backgroundColor('#785694')
  .margin({
    bottom: 50
  })
  .visibility(this.isDirectShowPlayPanel ? Visibility.Visible : Visibility.None)
  .position({ y: 600 })
  .transition(
    TransitionEffect
      .move(TransitionEdge.BOTTOM)
      .animation({
        duration: 500,
        curve: Curve.Friction
      })
  )
}
Enter fullscreen mode Exit fullscreen mode

Use onTouch to listen for global swipe gestures. Obtain the event object, and in the TouchType.Up callback, get the swipe distance and duration to calculate swipe speed.

A positive speed indicates a downward swipe (show the purple component), while a negative speed indicates an upward swipe (hide the purple component).

Note: Up/down swipes control the purple component’s visibility.

Code example:

onTouch((event: TouchEvent) => {
  if (!event) {
    return;
  }
  switch (event.type) {
    case TouchType.Down:
      this.startX = event.touches[0].displayX;
      this.startY = event.touches[0].displayY;
      this.startTime = event.timestamp;
      break;
    case TouchType.Move:
      break;
    case TouchType.Up:
      let endX = event.touches[0].displayX;
      let endY = event.touches[0].displayY;
      console.info('aptx', 'endY=' + endY + ', this.startY=' + this.startY);
      let endTime = event.timestamp;
      let deltaTime = (endTime - this.startTime) / 1000000000;
      let speed = (endY - this.startY) / (deltaTime == 0 ? 1 : deltaTime);
      if (Math.abs(speed) > 800) {
        if (speed < 0) {
          this.isShowPlayPanel = false;
          this.isDirectShowPlayPanel = false;
        } else if (speed > 0) {
          this.isDirectShowPlayPanel = true;
          this.isShowPlayPanel = true;
        }
      }
      break;
  }
})
Enter fullscreen mode Exit fullscreen mode

Code Snippet

  1. Index.ets
   @Entry
   @Component
   struct Index {
     @State message: string = 'Orientation Switch';
     @Provide('pageStack') pageStack: NavPathStack = new NavPathStack()
     @State startX: number = 0
     @State startY: number = 0
     @State startTime: number = 0
     @Provide('isShow') isShowPlayPanel: boolean = false
     @Provide('isDirectShow') isDirectShowPlayPanel: boolean = false

     build() {
       Navigation(this.pageStack) {
         Text(this.message)
           .id('HelloWorld')
           .fontSize(12)
           .margin({top: 25})
           .fontWeight(FontWeight.Bold)

         Text('Go to page1')
           .fontSize(20)
           .fontWeight(FontWeight.Bold)
           .backgroundColor(Color.Pink)
           .onClick(() => {
             this.pageStack.pushPathByName('page1', null, false);
           })

         if (this.isShowPlayPanel) {
           Stack() {

           }
           .width('100%')
           .height(80)
           .hitTestBehavior(HitTestMode.None)
           .backgroundColor('#785694')
           .margin({
             bottom: 50
           })
           .visibility(this.isDirectShowPlayPanel ? Visibility.Visible : Visibility.None)
           .position({ y: 100 })
           .transition(
             TransitionEffect
               .move(TransitionEdge.BOTTOM)
               .animation({
                 duration: 500,
                 curve: Curve.Friction
               })
           )
         }
       }
       .height('100%')
       .width('100%')
       .onTouch((event: TouchEvent) => {
         if (!event) {
           return;
         }
         switch (event.type) {
           case TouchType.Down:
             this.startX = event.touches[0].displayX;
             this.startY = event.touches[0].displayY;
             this.startTime = event.timestamp;
             break;
           case TouchType.Move:
             break;
           case TouchType.Up:
             let endX = event.touches[0].displayX;
             let endY = event.touches[0].displayY;
             console.info('aptx', 'endY=' + endY + ', this.startY=' + this.startY);
             let endTime = event.timestamp;
             let deltaTime = (endTime - this.startTime) / 1000000000;
             let speed = (endY - this.startY) / (deltaTime === 0 ? 1 : deltaTime);
             if (Math.abs(speed) > 100) {
               if (speed < 0) {
                 this.isShowPlayPanel = false;
                 this.isDirectShowPlayPanel = false;
               } else if (speed > 0) {
                 this.isDirectShowPlayPanel = true;
                 this.isShowPlayPanel = true;
               }
             }
             break;
         }
       })
     }
   }
Enter fullscreen mode Exit fullscreen mode
  1. Page1.ets
   @Component
   export struct Page1 {
     @Consume('pageStack') pageStack: NavPathStack
     @Consume('isShow') isShowPlayPanel: boolean
     @Consume('isDirectShow') isDirectShowPlayPanel: boolean

     build() {
       NavDestination() {
         Text('Go to page2')
           .fontSize(20)
           .fontWeight(FontWeight.Bold)
           .backgroundColor(Color.Pink)
           .margin({top: 37})
           .onClick(() => {
             let pathInfo: NavPathInfo = new NavPathInfo('page2', null)
             this.pageStack.pushDestination(pathInfo, false);
           })

         if (this.isShowPlayPanel) {
           Stack() {

           }
           .width('100%')
           .height(80)
           .hitTestBehavior(HitTestMode.None)
           .backgroundColor('#785694')
           .margin({
             bottom: 50
           })
           .visibility(this.isDirectShowPlayPanel ? Visibility.Visible : Visibility.None)
           .position({ y: 150 })
           .transition(
             TransitionEffect
               .move(TransitionEdge.BOTTOM)
               .animation({
                 duration: 500,
                 curve: Curve.Friction
               })
           )
         }
       }
       .width('100%')
       .height('100%')
     }
   }

   @Builder
   export function getPage1RouterMap(): void {
     Page1();
   }
Enter fullscreen mode Exit fullscreen mode

Test Results

cke_2312.gif

Limitations or Considerations

This example supports API Version 19 Release and above.

This example supports HarmonyOS 5.1.1 Release SDK and above.

This example must be compiled and run using DevEco Studio 5.1.1 Release or later.

Written by Bunyamin Akcay

Top comments (0)