OpenHarmony开发者论坛
标题:
OpenHarmony应用组件自定义事件分发
[打印本页]
作者:
深开鸿_张守忠
时间:
2024-1-16 19:57
标题:
OpenHarmony应用组件自定义事件分发
[md]### 简介:
** ArkUI在处理触屏事件时,会在触屏事件触发前进行按压点和组件区域的触摸测试,来收集需要响应触屏事件的组件,再基于触摸测试结果分发相应的触屏事件。在父节点,可以通过onChildTouchTest决定如何让子节点去做触摸测试,影响子组件的触摸测试,最终影响后续的触屏事件分发 。**
### 文档环境:
* **开发环境:Windows 10专业版**
* **DevEco Studio版本:DevEco Studio 4.0Release (4.0.0.600)**
* **SDK版本:4.1.6.1 (full sdk)**
* **API版本:Version 11**
* **开发板型号:DAYU200(RK3568)**
* **系统版本:OpenHarmony 4.1.6.1**
### 演示demo:
* **新建一个 Stage 框架的 demo 工程,在page/Index.ets中通过stack组件封装大小两个圆形按钮组件,分别用蓝色和黄色的背景色来区分并分别增加OnClick事件,在事件回调函数中调用提示组件,提示OnClick事件已响应。**
* **在stack组件中增加onChildTouchTest属性,在其回调函数中通过 对参数TouchTestInfo进行解析,判断按压点是否在大圆小圆内或者在大圆外,如果在小圆内则向小圆分发事件,如果在大圆内但在小圆外则向小圆分发事件,其他情况不向大圆和小圆分发事件。**
** demo运行效果:**
| **首页** | **点击蓝圈** | **点击黄圈** |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ![image](file://D:/project/OpenHarmony_sample/sample_%E9%9C%80%E6%B1%82&%E8%AF%A6%E7%BB%86%E8%AE%BE%E8%AE%A1/custom_event/%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91/screenshots/customClick.jpeg?lastModify=1705406242) | ![image](file://D:/project/OpenHarmony_sample/sample_%E9%9C%80%E6%B1%82&%E8%AF%A6%E7%BB%86%E8%AE%BE%E8%AE%A1/custom_event/%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91/screenshots/customClickBig.jpeg?lastModify=1705406242) | ![image](file://D:/project/OpenHarmony_sample/sample_%E9%9C%80%E6%B1%82&%E8%AF%A6%E7%BB%86%E8%AE%BE%E8%AE%A1/custom_event/%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91/screenshots/customClickSmall.jpeg?lastModify=1705406242) |
** 核心代码如下:**
```
import ShowToast from 'ShowToast';
import Logger from 'util/Logger';
const TAG: string = 'CustomClickEvent';
@Entry
@Component
struct CustomClickEvent {
private btnFontColor: Resource = $r('app.color.white');
isTouchPointInCircle(info: TouchTestInfo): boolean {
let circleCenterX = info.rect.x + info.rect.width / 2;
let circleCenterY = info.rect.y + info.rect.height / 2;
let circleRadius = info.rect.width / 2;
let distance = Math.sqrt((circleCenterX - info.parentX)**2 + (circleCenterY - info.parentY)**2);
Logger.info(TAG, `TouchPoinInCircle circleCenterX: ${circleCenterX}, circleCenterY: ${circleCenterY},\
circleRadius: ${circleRadius}, distance: ${distance}`);
if (distance <= circleRadius) {
return true;
}
return false;
}
build() {
Column() {
Column() {
Column({ space: 12 }) {
Stack({ alignContent: Alignment.Bottom }) {
Button({ type: ButtonType.Circle }) {
Row() {
Text($r('app.string.custom_click_big_btn'))
.fontSize(21)
.fontWeight(500)
.fontFamily('HarmonyHeiTi-Medium')
.textAlign(TextAlign.Center)
.id('BigCircle')
.padding({ top: 56, bottom: 300 })
}
.alignItems(VerticalAlign.Top)
}
.backgroundColor('#007DFF')
.width('100%')
.height('100%')
.fontSize(21)
.fontWeight(500)
.fontColor(this.btnFontColor)
.onClick(() => {
ShowToast.longToast($r('app.string.custom_bigcircle_prompt'));
})
Button($r('app.string.custom_click_small_btn'), { type: ButtonType.Circle })
.backgroundColor('#F7CE00')
.width(240)
.fontSize(21)
.fontWeight(500)
.borderRadius(20)
.fontColor(this.btnFontColor)
.id('SmallCircle')
.onClick(() => {
ShowToast.longToast($r('app.string.custom_smallcircle_prompt'));
})
}
.width('100%')
.hitTestBehavior(HitTestMode.Block)
.onChildTouchTest((touchinfo) => {
for(let i = 0; i < touchinfo.length; i++) {
let info: TouchTestInfo = touchinfo
;
if (info.id == 'SmallCircle' && info.x > 0 && info.y > 0 && this.isTouchPointInCircle(info) == true) {
Logger.info(TAG, `touchinfo touch point at scope of component: ${info.id}`);
return { id: 'SmallCircle', strategy: TouchTestStrategy.FORWARD };
}
if (info.id == 'BigCircle' && info.x > 0 && info.y > 0 && this.isTouchPointInCircle(info) == true) {
Logger.info(TAG, `touchinfo touch point at scope of component: ${info.id}`);
return { id: 'BigCircle', strategy: TouchTestStrategy.FORWARD };
}
}
return { strategy: TouchTestStrategy.DEFAULT };
})
}
.padding({ left: 24, right: 24, bottom: 32 })
Column() {
Row() {
Button({ type: ButtonType.Circle })
.backgroundColor('#007DFF')
.width(8)
.height(8)
Text($r('app.string.big_circle_prompt'))
.fontSize(14)
.fontWeight(400)
.fontFamily('HarmonyHeiTi')
.textAlign(TextAlign.Start)
.margin({ left: 8 })
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
Row() {
Button({ type: ButtonType.Circle })
.backgroundColor('#F7CE00')
.width(8)
.height(8)
Text($r('app.string.small_circle_prompt'))
.fontSize(14)
.fontWeight(400)
.fontFamily('HarmonyHeiTi')
.textAlign(TextAlign.Start)
.margin({ left: 8 })
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
}
}
.height('90%')
.width('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.flexShrink(1)
}
.height('100%')
.width('100%')
.backgroundColor($r('app.color.background_shallow_grey'))
}
}
```
### sample仓地址:
**本功能的sample仓地址:**[
https://gitee.com/openharmony/applications
\_app\_samples/tree/master/code/UI/ArkTsComponentCollection/ComponentCollection](
https://gitee.com/openharmony/ap ... ComponentCollection
)
[/md]
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/)
Powered by Discuz! X3.5