鸿蒙开发笔记(二十六):交互事件--触摸,按键,鼠标,焦点

本文围绕鸿蒙开发中的交互事件展开,介绍了触屏、键鼠、按键和焦点事件。触屏事件含点击、拖拽和触摸;键鼠事件包括鼠标和按键操作;按键事件经特定流程处理;焦点事件涉及基本概念、走焦规则等,还介绍了监听焦点变化、设置组件获焦等方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

交互事件按照触发类型来分类,包括触屏事件、键鼠事件和焦点事件。

  • 触屏事件:手指或手写笔在触屏上的单指或单笔操作。

  • 键鼠事件:包括外设鼠标或触控板的操作事件和外设键盘的按键事件。
    鼠标事件是指通过连接和使用外设鼠标/触控板操作时所响应的事件。
    按键事件是指通过连接和使用外设键盘操作时所响应的事件。

  • 焦点事件:通过以上方式控制组件焦点的能力和响应的事件。

手势事件由绑定手势方法和绑定的手势组成,绑定的手势可以分为单一手势和组合手势两种类型,根据手势的复杂程度进行区分。

  • 绑定手势方法:用于在组件上绑定单一手势或组合手势,并声明所绑定的手势的响应优先级。

  • 单一手势:手势的基本单元,是所有复杂手势的组成部分。

  • 组合手势:由多个单一手势组合而成,可以根据声明的类型将多个单一手势按照一定规则组合成组合手势,并进行使用。

1. 触屏事件

触屏事件指当手指/手写笔在组件上按下、滑动、抬起时触发的回调事件。包括点击事件、拖拽事件和触摸事件。

触摸事件原理

在这里插入图片描述

1.1 点击事件

点击事件是指通过手指或手写笔做出一次完整的按下和抬起动作。当发生点击事件时,会触发以下回调函数:

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

event参数提供点击事件相对于窗口或组件的坐标位置,以及发生点击的事件源。

例如通过按钮的点击事件控制图片的显示和隐藏。

@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';
          } else {
   
            this.btnMsg = 'show';
          }
          // 点击Button控制Image的显示和消失
          this.flag = !this.flag;
        })
      if (this.flag) {
   
        Image($r('app.media.icon')).width(200).height(200)
      }
    }.height('100%').width('100%')
  }
}

1.2 拖拽事件

拖拽事件指手指/手写笔长按组件(>=500ms),并拖拽到接收区域释放的事件。拖拽事件触发流程:

在这里插入图片描述
拖拽事件的触发通过长按、拖动平移判定,手指平移的距离达到5vp即可触发拖拽事件。ArkUI支持应用内、跨应用的拖拽事件。

拖拽事件提供以下接口:

在这里插入图片描述
如下是跨窗口拖拽,拖出窗口示例:

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%')
  }
}

1.3 触摸事件

当手指或手写笔在组件上触碰时,会触发不同动作所对应的事件响应,包括按下(Down)、滑动(Move)、抬起(Up)事件:

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

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

  • event.type为TouchType.Move:表示手指按住移动。

触摸事件可以同时多指触发,通过event参数可获取触发的手指位置、手指唯一标志、当前发生变化的手指和输入的设备源等信息。

// 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 + ','
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值