源码 https://github.com/webabcd/HarmonyDemo
作者 webabcd
开天辟地 HarmonyOS(鸿蒙) - 输入: 触摸类输入
示例如下:
pages\input\TouchDemo.ets
/** 触摸类输入* 点击事件,触摸事件,拖拽事件,事件冒泡,事件透传*/import { TitleBar } from '../TitleBar';
import { unifiedDataChannel, uniformTypeDescriptor } from '@kit.ArkData';@Entry
@Component
struct TouchDemo {build() {Column() {TitleBar()Tabs() {TabContent() { MySample1() }.tabBar('点击事件').align(Alignment.Top)TabContent() { MySample2() }.tabBar('触摸事件').align(Alignment.Top)TabContent() { MySample3() }.tabBar('拖拽事件').align(Alignment.Top)TabContent() { MySample4() }.tabBar('事件冒泡').align(Alignment.Top)TabContent() { MySample5() }.tabBar('事件透传').align(Alignment.Top)}.scrollable(true).barMode(BarMode.Scrollable).layoutWeight(1)}}
}@Component
struct MySample1 {@State message: string = ""build() {Column({ space: 10 }) {Text(this.message)/** onClick() - 点击事件,当按下并抬起后触发(回调参数是一个 ClickEvent 对象)* x, y - 点击位置相对于组件左上角的坐标* windowX, windowY - 点击位置相对于窗口的坐标* displayX, displayY - 点击位置相对于屏幕的坐标* timestamp - 事件触发时,距系统启动时的时间戳* target.area - 触发了事件的组件的显示区域(一个 Area 对象)* width, height - 尺寸* position - 区域的左上角相对于父容器的左上角的位置* globalPosition - 区域的左上角相对于页面的左上角的位置*/Button('click me').onClick((event: ClickEvent) => {this.message = "onClick\n"this.message += `x:${event.x}\n`this.message += `y:${event.y}\n`this.message += `windowX:${event.windowX}\n`this.message += `windowY:${event.windowY}\n`this.message += `displayX:${event.displayX}\n`this.message += `displayY:${event.displayY}\n`this.message += `timestamp:${event.timestamp}\n`this.message += `target area width:${event.target.area.width}\n`this.message += `target area height:${event.target.area.height}\n`this.message += `target area position:${JSON.stringify(event.target.area.position)}\n`this.message += `target area globalPosition:${JSON.stringify(event.target.area.globalPosition)}\n`})}}
}@Component
struct MySample2 {@State message: string = ""build() {Column({ space: 10 }) {Text(this.message)/** onTouch() - 触摸事件,当按下或滑动或抬起时触发(回调参数是一个 TouchEvent 对象)* type - 触摸的类型(TouchEvent 枚举)* Down, Up, Move* touches - 当前全部的触摸点的信息(一个 TouchObject 对象数组)* changedTouches - 当前发生变化的触摸点的信息(一个 TouchObject 对象数组)** TouchObject - 触摸点信息* x, y - 触摸点的位置相对于组件左上角的坐标* windowX, windowY - 触摸点的位置相对于窗口的坐标* displayX, displayY - 触摸点的位置相对于屏幕的坐标* timestamp - 事件触发时,距系统启动时的时间戳* target.area - 触发了事件的组件的显示区域(一个 Area 对象)* width, height - 尺寸* position - 区域的左上角相对于父容器的左上角的位置* globalPosition - 区域的左上角相对于页面的左上角的位置*/Button('click me').onTouch((event: TouchEvent) => {let touches = event.toucheslet changedTouches = event.changedTouchesthis.message = "onTouch\n"this.message += `type:${TouchType[event.type]}\n`this.message += `x:${touches[0].x}\n`this.message += `y:${touches[0].y}\n`this.message += `windowX:${touches[0].windowX}\n`this.message += `windowY:${touches[0].windowY}\n`this.message += `displayX:${touches[0].displayX}\n`this.message += `displayY:${touches[0].displayY}\n`this.message += `timestamp:${event.timestamp}\n`this.message += `target area width:${event.target.area.width}\n`this.message += `target area height:${event.target.area.height}\n`this.message += `target area position:${JSON.stringify(event.target.area.position)}\n`this.message += `target area globalPosition:${JSON.stringify(event.target.area.globalPosition)}\n`})}}
}@Component
struct MySample3 {@State message: string = ""@State targetText: string = ""@State targetImage: string = ""build() {Column({space:10}) {Text(this.message)/** draggable() - 是否支持按下后的拖拽操作* allowDrop() - 当拖拽组件落入当前组件时,指定允许传递的数据类型(一个 UniformDataType 枚举数组)* PLAIN_TEXT, IMAGE, 等** onDragStart() - 拖拽开始时的回调(当长按时间大于 500 毫秒,且拖拽距离大于 10vp 时触发回调)* onPreDrag() - 拖拽发起前的回调* onDragEnd() - 拖拽完成后的回调** onDrop() - 当拖拽组件在当前组件释放时的回调* onDragEnter(), onDragMove(), onDragLeave() - 当拖拽组件进入当前组件,在当前组件上移动,离开当前组件时的回调(当监听了 onDrop() 时才会生效)*/Text('text').border({ color: Color.Black, width: 1 }).width('100%').height(100).draggable(true).onDragStart((event: DragEvent) => {this.message = `onDragStart`// 设置 PlainText 类型的拖拽数据let data: unifiedDataChannel.PlainText = new unifiedDataChannel.PlainText();data.textContent = 'textContent';event.setData(new unifiedDataChannel.UnifiedData(data));}).onPreDrag((status: PreDragStatus) => {this.message = `onPreDrag:${status}`}).onDragEnd((event: DragEvent) => {// 通过 event.getResult() 获取 drop 的结果(即在 onDrop() 中通过 event.setResult() 设置的结果)this.message = `onDragEnd:${DragResult[event.getResult()]}`})Text(this.targetText).border({ color: Color.Black, width: 1 }).width('100%').height(100).allowDrop([uniformTypeDescriptor.UniformDataType.PLAIN_TEXT]).onDrop((event: DragEvent) => {let data: UnifiedData = event.getData();if (!data) {return;}let records: Array<unifiedDataChannel.UnifiedRecord> = data.getRecords();if (!records || records.length <= 0) {return;}// 获取 PlainText 类型的拖拽数据let plainText: unifiedDataChannel.PlainText = records[0] as unifiedDataChannel.PlainText;this.targetText = plainText.textContent;// 设置 drop 的结果event.setResult(DragResult.DRAG_SUCCESSFUL);}).onDragEnter((event: DragEvent) => {this.message = `onDragEnter`}).onDragMove((event: DragEvent) => {this.message = `onDragMove`}).onDragLeave((event: DragEvent) => {this.message = `onDragLeave`})Image($r('app.media.app_icon')).width(100).height(100).draggable(true).onDragEnd((event: DragEvent) => {// 通过 event.getResult() 获取 drop 的结果(即在 onDrop() 中通过 event.setResult() 设置的结果)this.message = `onDragEnd:${DragResult[event.getResult()]}`})Image(this.targetImage).width(100).height(100).border({ color: Color.Black, width: 1 }).allowDrop([uniformTypeDescriptor.UniformDataType.IMAGE]).onDrop((event: DragEvent) => {let data: UnifiedData = event.getData();if (!data) {return;}let records: Array<unifiedDataChannel.UnifiedRecord> = data.getRecords();if (!records || records.length <= 0) {return;}// 获取拖拽的图片的地址this.targetImage = (records[0] as unifiedDataChannel.Image).imageUri;// 设置 drop 的结果event.setResult(DragResult.DRAG_SUCCESSFUL);})}}
}@Component
struct MySample4 {@State message: string = ""build() {Column({space:10}) {Text(this.message)/** 父子组件场景下* onTouch() 事件默认是支持冒泡的,如果不需要冒泡则调用 event.stopPropagation() 即可*/Column() {Column() {Column() {}.width(100).height(100).backgroundColor(Color.Red).onTouch(() => {this.message += "r"})}.width(200).height(200).backgroundColor(Color.Green).onTouch(() => {this.message += "g"})}.width(300).height(300).backgroundColor(Color.Blue).onTouch(() => {this.message += "b"})Column() {Column() {Column() {}.width(100).height(100).backgroundColor(Color.Red).onTouch((event: TouchEvent) => {event.stopPropagation()this.message += "r"})}.width(200).height(200).backgroundColor(Color.Green).onTouch((event: TouchEvent) => {event.stopPropagation()this.message += "g"})}.width(300).height(300).backgroundColor(Color.Blue).onTouch((event: TouchEvent) => {event.stopPropagation()this.message += "b"})}}
}@Component
struct MySample5 {@State message: string = ""build() {Column({space:10}) {Text(this.message)/** 兄弟组件场景下* onTouch() 事件默认是不支持透传的,如果需要透传则调用 hitTestBehavior(HitTestMode.Transparent) 即可*/Stack() {Column().width(300).height(300).backgroundColor(Color.Blue).onTouch(() => {this.message += "b"})Column().width(200).height(200).backgroundColor(Color.Green).onTouch(() => {this.message += "g"})Column().width(100).height(100).backgroundColor(Color.Red).onTouch(() => {this.message += "r"})}.width(300).height(300)Stack() {Column().width(300).height(300).backgroundColor(Color.Blue).onTouch(() => {this.message += "b"}).hitTestBehavior(HitTestMode.Transparent)Column().width(200).height(200).backgroundColor(Color.Green).onTouch(() => {this.message += "g"}).hitTestBehavior(HitTestMode.Transparent)Column().width(100).height(100).backgroundColor(Color.Red).onTouch(() => {this.message += "r"}).hitTestBehavior(HitTestMode.Transparent)}.width(300).height(300)}}
}
源码 https://github.com/webabcd/HarmonyDemo
作者 webabcd