如果你也对鸿蒙开发感兴趣,加入“Harmony自习室”吧!扫描下方名片,关注公众号,公众号更新更快,同时也有更多学习资料和技术讨论群。

1 概 述
事件是人机交互的基础,鸿蒙开发中,事件分为两大类:a)通用事件;b)手势事件。
👉🏻 通用事件
通用事件又可以按照触发类型来分类,分为三大类:触屏事件、键鼠事件和焦点事件。
-
触屏事件:手指或手写笔在触屏上的单指或单笔操作。
-
键鼠事件:包括外设鼠标或触控板的操作事件和外设键盘的按键事件。
-
鼠标事件是指通过连接和使用外设鼠标/触控板操作时所响应的事件。
-
按键事件是指通过连接和使用外设键盘操作时所响应的事件。
-
-
焦点事件:通过以上方式控制组件焦点的能力和响应的事件。
👉🏻 手势事件
手势事件由绑定手势方法和绑定的手势组成,绑定的手势可以分为单一手势和组合手势两种类型,根据手势的复杂程度进行区分。
-
绑定手势方法:用于在组件上绑定单一手势或组合手势,并声明所绑定的手势的响应优先级。
-
单一手势:手势的基本单元,是所有复杂手势的组成部分。
-
组合手势:由多个单一手势组合而成,可以根据声明的类型将多个单一手势按照一定规则组合成组合手势,并进行使用。
下面,我们先了解下最常用事件:触屏事件,即:点击、拖拽、触摸事件。
2 点 击 事 件
点击事件是指通过手指或手写笔做出一次完整的按下和抬起动作。当发生点击事件时,会触发以下回调函数:
onClick(event: (event?: ClickEvent) => void)
event参数提供点击事件相对于窗口或组件的坐标位置,以及发生点击的事件源。
例如通过按钮的点击事件控制图片的显示和隐藏,代码如下:
@Entry@Componentstruct 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%')}}
3 拖 拽 事 件
拖拽事件指手指/手写笔长按组件(>=500ms),并拖拽到接收区域释放的事件。拖拽事件触发流程:

拖拽事件的触发通过长按、拖动平移判定,手指平移的距离达到5vp即可触发拖拽事件。ArkUI支持应用内、跨应用的拖拽事件。
拖拽事件提供以下接口,整理展示如下:

如下是跨窗口拖拽,拖出窗口示例:
import image from '@ohos.multimedia.image';@Entry@Componentstruct Index {@State visible: Visibility = Visibility.Visibleprivate pixelMapReader = undefinedaboutToAppear() {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;})}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@Componentstruct 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.Nonescroller: 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%')}}
4 触 摸 事 件
当手指或手写笔在组件上触碰时,会触发不同动作所对应的事件响应,包括按下(Down)、滑动(Move)、抬起(Up)事件:
onTouch(event: (event?: TouchEvent) => void)
-
-
event.type为TouchType.Down:表示手指按下。
-
event.type为TouchType.Up:表示手指抬起。
-
event.type为TouchType.Move:表示手指按住移动。
-
触摸事件可以同时多指触发,通过event参数可获取触发的手指位置、手指唯一标志、当前发生变化的手指和输入的设备源等信息。
// xxx.ets@Entry@Componentstruct 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)}}




















