鴻蒙HarmonyOS實戰-ArkUI事件(觸屏事件)

蜀道山QAQ發表於2024-04-25

🚀前言

觸屏事件是指透過觸控螢幕來進行操作和互動的事件。常見的觸屏事件包括點選(tap)、雙擊(double tap)、長按(long press)、滑動(swipe)、拖動(drag)等。觸屏事件通常用於移動裝置和平板電腦等具有觸控螢幕的裝置上,使用者可以透過觸控螢幕上的不同區域或者以不同的方式進行操作,從而實現各種功能和互動效果。觸屏事件可以被應用程式或者作業系統捕捉並響應,以實現使用者與裝置之間的互動。

🚀一、觸屏事件

在HarmonyOS中,觸屏事件包括點選事件、拖拽事件和觸控事件,開發者可以透過使用HarmonyOS的觸控事件處理機制來捕獲和處理這些事件。

  1. 點選事件(Click Event):當使用者在螢幕上單擊時觸發。開發者可以透過重寫onTouch或onTouchEvent方法來監聽並處理點選事件。在處理點選事件時,可以獲取點選位置的座標、點選的View等資訊。

  2. 拖拽事件(Drag Event):當使用者在螢幕上按住並拖動時觸發。開發者可以透過重寫onTouch或onTouchEvent方法來監聽並處理拖拽事件。在處理拖拽事件時,可以獲取當前拖拽的位置、起始位置、拖拽的View等資訊。

  3. 觸控事件(Touch Event):觸控事件是一系列的事件,包括按下、抬起、移動等。開發者可以透過重寫onTouch或onTouchEvent方法來監聽並處理觸控事件。在處理觸控事件時,可以獲取觸控的位置、觸控的View等資訊。

除了重寫onTouch或onTouchEvent方法來處理觸控事件外,開發者還可以使用View.OnTouchListener介面來監聽和處理觸控事件。透過設定View的OnTouchListener,可以實現對觸控事件的更加靈活的控制和處理。

觸控事件原理:

image

🔎1.點選事件

點選事件是指使用者透過滑鼠或觸控式螢幕等輸入裝置點選(或觸控)頁面上的元素時觸發的一種響應機制。當使用者點選一個元素時會捕捉到點選事件,並執行相應的處理程式碼。點選事件常用於實現使用者互動,比如點選按鈕提交表單、點選連結跳轉頁面等操作。

介面如下:

onClick(event: (event?: ClickEvent) => void)

案例如下:

@Entry
@Component
struct IfElseTransition {
  @State flag: boolean = true;
  @State btnMsg: string = 'show';

  build() {
    Column() {
      Button(this.btnMsg).width(80).height(30).margin(30)
        .onClick(() => {
          if (this.flag) {
            this.btnMsg = 'hide';
            console.log('hide');
          } else {
            this.btnMsg = 'show';
            console.log('show');
          }
          // 點選Button控制Image的顯示和消失
          this.flag = !this.flag;
        })
      if (this.flag) {
        Image($r('app.media.icon')).width(200).height(200)
      }
    }.height('100%').width('100%')
  }
}

image

🔎2.拖拽事件

拖拽事件是一種使用者互動行為,指的是在計算機中,使用者透過滑鼠或觸控式螢幕按住某個元素,拖動它並釋放的操作。拖拽事件通常分為三個階段:開始拖拽、正在拖拽和結束拖拽。開始拖拽階段是指當使用者按住要拖拽的元素時觸發的事件。正在拖拽階段是指使用者持續拖動元素時觸發的事件。結束拖拽階段是指使用者釋放滑鼠或手指時觸發的事件。拖拽事件可以用於實現一些互動效果,例如拖拽排序、拖拽放置和拖拽改變元素位置等。

介面如下:

image

案例如下:

拖出窗體

import image from '@ohos.multimedia.image';

@Entry
@Component
struct Index {
  @State visible: Visibility = Visibility.Visible
  private pixelMapReader = undefined

  aboutToAppear() {
    console.info('begin to create pixmap has info message: ')
    this.createPixelMap()
  }

  createPixelMap() {
    let color = new ArrayBuffer(4 * 96 * 96);
    var buffer = new Uint8Array(color);
    for (var i = 0; i < buffer.length; i++) {
      buffer[i] = (i + 1) % 255;
    }
    let opts = {
      alphaType: 0,
      editable: true,
      pixelFormat: 4,
      scaleMode: 1,
      size: { height: 96, width: 96 }
    }
    const promise = image.createPixelMap(color, opts);
    promise.then((data) => {
      console.info('create pixmap has info message: ' + JSON.stringify(data))
      this.pixelMapReader = data;
    })
  }

  @Builder pixelMapBuilder() {
    Text('drag item')
      .width('100%')
      .height(100)
      .fontSize(16)
      .textAlign(TextAlign.Center)
      .borderRadius(10)
      .backgroundColor(0xFFFFFF)
  }

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Text('App1')
        .width('40%')
        .height(80)
        .fontSize(20)
        .margin(30)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Pink)
        .visibility(Visibility.Visible)

      Text('Across Window Drag This')
        .width('80%')
        .height(80)
        .fontSize(16)
        .margin(30)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Pink)
        .visibility(this.visible)
        .onDragStart(() => {                    //啟動跨視窗拖拽
          console.info('Text onDrag start')
          return { pixelMap: this.pixelMapReader, extraInfo: 'custom extra info.' }
        })
        .onDrop((event: DragEvent, extraParams: string) => {
          console.info('Text onDragDrop,  ')
          this.visible = Visibility.None                    //拖動結束後,使源不可見
        })
    }

    .width('100%')
    .height('100%')
  }
}

拖入窗體

@Entry
@Component
struct Index {
  @State number: string[] = ['drag here']
  @State text: string = ''
  @State bool1: boolean = false
  @State bool2: boolean = false
  @State visible: Visibility = Visibility.Visible
  @State visible2: Visibility = Visibility.None
  scroller: Scroller = new Scroller()

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Text('App2')
        .width('40%')
        .height(80)
        .fontSize(20)
        .margin(30)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Pink)
        .visibility(Visibility.Visible)

      List({ space: 20, initialIndex: 0 }) {
        ForEach(this.number, (item) => {
          ListItem() {
            Text('' + item)
              .width('100%')
              .height(80)
              .fontSize(16)
              .borderRadius(10)
              .textAlign(TextAlign.Center)
              .backgroundColor(0xFFFFFF)
          }
        }, item => item)

        ListItem() {
          Text('Across Window Drag This')
            .width('80%')
            .height(80)
            .fontSize(16)
            .margin(30)
            .textAlign(TextAlign.Center)
            .backgroundColor(Color.Pink)
            .visibility(this.visible2)
        }
      }
      .height('50%')
      .width('90%')
      .border({ width: 1 })
      .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 })
      .onDragEnter((event: DragEvent, extraParams: string) => {                         //拖拽進去元件
        console.info('List onDragEnter, ' + extraParams)
      })
      .onDragMove((event: DragEvent, extraParams: string) => {                          //拖拽時移動
        console.info('List onDragMove, ' + extraParams)
      })
      .onDragLeave((event: DragEvent, extraParams: string) => {                         //拖拽離開元件
        console.info('List onDragLeave, ' + extraParams)
      })
      .onDrop((event: DragEvent, extraParams: string) => {                              //釋放元件
        console.info('List onDragDrop, ' + extraParams)
        this.visible2 = Visibility.Visible                                              //拖拽完成使拖入目標可見
      })
    }
    .width('100%')
    .height('100%')
  }
}

因為不好演示就不截圖了

🔎3.觸控事件

觸控事件是一種使用者與觸控式螢幕或觸控裝置進行互動的方式。當使用者透過手指或手寫筆觸控螢幕或其他觸控裝置時,裝置會檢測到並觸發相應的事件。觸控事件可以包括觸控開始、觸控移動、觸控結束、觸控取消等不同的操作狀態。

觸控事件常用於移動裝置,例如智慧手機、平板電腦等。透過觸控螢幕,使用者可以進行滑動、點選、縮放等操作,實現與裝置的互動。

在軟體開發中,可以透過監聽觸控事件,來響應使用者的觸控操作。開發者可以根據觸控事件的不同狀態,執行相應的操作,例如在使用者滑動螢幕時進行頁面切換,或者在使用者點選螢幕時進行按鈕點選等。觸控事件的處理可以透過各種程式語言和開發框架來實現。

介面如下:

onTouch(event: (event?: TouchEvent) => void)
  • event.type為TouchType.Down:表示手指按下。

  • event.type為TouchType.Up:表示手指抬起。

  • event.type為TouchType.Move:表示手指按住移動。

案例如下:

// xxx.ets
@Entry
@Component
struct TouchExample {
  @State text: string = '';
  @State eventType: string = '';

  build() {
    Column() {
      Button('Touch').height(40).width(100)
        .onTouch((event: TouchEvent) => {
          if (event.type === TouchType.Down) {
            this.eventType = 'Down';
          }
          if (event.type === TouchType.Up) {
            this.eventType = 'Up';
          }
          if (event.type === TouchType.Move) {
            this.eventType = 'Move';
          }
          this.text = 'TouchType:' + this.eventType + '\nDistance between touch point and touch element:\nx: '
          + event.touches[0].x + '\n' + 'y: ' + event.touches[0].y + '\nComponent globalPos:('
          + event.target.area.globalPosition.x + ',' + event.target.area.globalPosition.y + ')\nwidth:'
          + event.target.area.width + '\nheight:' + event.target.area.height
        })
      Button('Touch').height(50).width(200).margin(20)
        .onTouch((event: TouchEvent) => {
          if (event.type === TouchType.Down) {
            this.eventType = 'Down';
          }
          if (event.type === TouchType.Up) {
            this.eventType = 'Up';
          }
          if (event.type === TouchType.Move) {
            this.eventType = 'Move';
          }
          this.text = 'TouchType:' + this.eventType + '\nDistance between touch point and touch element:\nx: '
          + event.touches[0].x + '\n' + 'y: ' + event.touches[0].y + '\nComponent globalPos:('
          + event.target.area.globalPosition.x + ',' + event.target.area.globalPosition.y + ')\nwidth:'
          + event.target.area.width + '\nheight:' + event.target.area.height
        })
      Text(this.text)
    }.width('100%').padding(30)
  }
}

image

🚀寫在最後

  • 如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
  • 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
  • 關注小編,同時可以期待後續文章ing🚀,不定期分享原創知識。
  • 更多鴻蒙最新技術知識點,請關注作者部落格:https://t.doruo.cn/14DjR1rEY

image

相關文章