自定义事件分发
ArkUI在处理触屏事件时,会在触屏事件触发前进行按压点和组件区域的触摸测试,来收集需要响应触屏事件的组件,再基于触摸测试结果分发相应的触屏事件。在父节点,开发者可以通过onChildTouchTest决定如何让子节点去做触摸测试,影响子组件的触摸测试,最终影响后续的触屏事件分发,具体影响参考TouchTestStrategy枚举说明。
说明:
从API Version 11开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
onClick以及旋转、捏合手势经过自定义事件分发之后可能会因为触摸热区没有命中导致事件不响应。
onChildTouchTest
onChildTouchTest(event: (value: Array<TouchTestInfo>) => TouchResult): T
当前组件可通过设置回调来自定义子节点如何去做触摸测试。
原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。
系统能力: SystemCapability.ArkUI.ArkUI.Full
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
value | Array<TouchTestInfo> | 是 | 包含子节点信息的数组。 |
返回值:
类型 | 说明 |
---|---|
T | 返回当前组件。 |
说明:
子节点信息数组中只包含命名节点的信息,即开发者通过id属性设置了id的节点。
TouchTestInfo
原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。
系统能力: SystemCapability.ArkUI.ArkUI.Full
名称 | 类型 | 描述 |
---|---|---|
windowX | number | 按压点相对于窗口左上角的x轴坐标。 |
windowY | number | 按压点相对于窗口左上角的y轴坐标。 |
parentX | number | 按压点相对于父组件左上角的x轴坐标。 |
parentY | number | 按压点相对于父组件左上角的y轴坐标。 |
x | number | 按压点相对于子组件左上角的x轴坐标。 |
y | number | 按压点相对于子组件左上角的y轴坐标。 |
rect | RectResult | 子组件的大小。 |
id | string | 通过id属性设置的组件id。 |
TouchResult
原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。
系统能力: SystemCapability.ArkUI.ArkUI.Full
名称 | 类型 | 必填 | 描述 |
---|---|---|---|
strategy | TouchTestStrategy | 是 | 事件派发策略。 |
id | string | 否 | 通过id属性设置的组件id。 当strategy为TouchTestStrategy.DEFAULT时,id是可选的;当strategy是TouchTestStrategy.FORWARD_COMPETITION或TouchTestStrategy.FORWARD时,id是必需的(如果没有返回id,则当成TouchTestStrategy.DEFAULT处理)。 |
TouchTestStrategy枚举说明
卡片能力: 从API version 11开始,该接口支持在ArkTS卡片中使用。
原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。
系统能力: SystemCapability.ArkUI.ArkUI.Full
名称 | 描述 |
---|---|
DEFAULT | 自定义分发不产生影响,继续走组件系统默认分发机制。 |
FORWARD_COMPETITION | 定向派发到指定子节点,同时走ArkUI触摸测试流程。 |
FORWARD | 定向派发到指定子节点,不走ArkUI触摸测试流程。 |
示例
示例1
// xxx.ets
import promptAction from '@ohos.promptAction';
@Entry
@Component
struct ListExample {
private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
@State text: string = 'Button'
build() {
Column() {
List({ space: 12, initialIndex: 0 }) {
ForEach(this.arr, (item: number) => {
ListItem() {
Text('Item ' + item)
.width('100%')
.height(56)
.fontSize(16)
.textAlign(TextAlign.Start)
}.borderRadius(24)
.backgroundColor(Color.White)
.padding({ left: 12, right: 12 })
}, (item: string) => item)
}
.listDirection(Axis.Vertical)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.Spring)
.onScrollIndex((start: number, end: number) => {
console.info('first' + start)
console.info('last' + end)
})
.onDidScroll((scrollOffset: number, scrollState: ScrollState) => {
console.info(`onScroll scrollState = ScrollState` + scrollState + `, scrollOffset = ` + scrollOffset)
})
.width('100%')
.height('65%')
.id('MyList')
Button(this.text)
.width(312)
.height(40)
.id('Mybutton')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.margin({ top: 80 })
.onClick(() => {
this.text = 'click the button'
promptAction.showToast({ message: 'you click the button.', duration: 3000 })
})
}
.width('100%')
.height('100%')
.backgroundColor(0xF1F3F5)
.justifyContent(FlexAlign.End)
.padding({ left: 12, right: 12, bottom: 24 })
.onChildTouchTest((touchinfo) => {
for (let info of touchinfo) {
if (info.id == 'MyList') {
return { id: info.id, strategy: TouchTestStrategy.FORWARD_COMPETITION }
}
}
return { strategy: TouchTestStrategy.DEFAULT }
})
}
}
ts
点击下方空白区域后拖动,能够拖动List滑动;点击Button按钮,Button会响应onClick事件。
示例2
// xxx.ets
import promptAction from '@ohos.promptAction';
@Entry
@Component
struct ListExample {
private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
@State text: string = 'Button'
build() {
Column() {
List({ space: 12, initialIndex: 0 }) {
ForEach(this.arr, (item: number) => {
ListItem() {
Text('Item ' + item)
.width('100%')
.height(56)
.fontSize(16)
.textAlign(TextAlign.Start)
}.borderRadius(24)
.backgroundColor(Color.White)
.padding({ left: 12, right: 12 })
}, (item: string) => item)
}
.listDirection(Axis.Vertical)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.Spring)
.onScrollIndex((start: number, end: number) => {
console.info('first' + start)
console.info('last' + end)
})
.onScroll((scrollOffset: number, scrollState: ScrollState) => {
console.info(`onScroll scrollState = ScrollState` + scrollState + `, scrollOffset = ` + scrollOffset)
})
.width('100%')
.height('65%')
.id('MyList')
Button(this.text)
.width(312)
.height(40)
.id('Mybutton')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.margin({ top: 80 })
.onClick(() => {
this.text = 'click the button'
promptAction.showToast({ message: 'you click the button.', duration: 3000 })
})
}
.width('100%')
.height('100%')
.backgroundColor(0xF1F3F5)
.justifyContent(FlexAlign.End)
.padding({ left: 12, right: 12, bottom: 24 })
.onChildTouchTest((touchinfo) => {
for (let info of touchinfo) {
if (info.id == 'MyList') {
return { id: info.id, strategy: TouchTestStrategy.FORWARD }
}
}
return { strategy: TouchTestStrategy.DEFAULT }
})
}
}
ts
点击下方空白区域后拖动,能够拖动List滑动;点击Button按钮,Button不会响应onClick事件。
示例3
// xxx.ets
import promptAction from '@ohos.promptAction';
@Entry
@Component
struct ListExample {
private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
@State text: string = 'Button'
build() {
Column() {
List({ space: 12, initialIndex: 0 }) {
ForEach(this.arr, (item: number) => {
ListItem() {
Text('Item ' + item)
.width('100%')
.height(56)
.fontSize(16)
.textAlign(TextAlign.Start)
}.borderRadius(24)
.backgroundColor(Color.White)
.padding({ left: 12, right: 12 })
}, (item: string) => item)
}
.listDirection(Axis.Vertical)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.Spring)
.onScrollIndex((start: number, end: number) => {
console.info('first' + start)
console.info('last' + end)
})
.onScroll((scrollOffset: number, scrollState: ScrollState) => {
console.info(`onScroll scrollState = ScrollState` + scrollState + `, scrollOffset = ` + scrollOffset)
})
.width('100%')
.height('65%')
.id('MyList')
Button(this.text)
.width(312)
.height(40)
.id('Mybutton')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.margin({ top: 80 })
.onClick(() => {
this.text = 'click the button'
promptAction.showToast({ message: 'you click the button.', duration: 3000 })
})
}
.width('100%')
.height('100%')
.backgroundColor(0xF1F3F5)
.justifyContent(FlexAlign.End)
.padding({ left: 12, right: 12, bottom: 24 })
.onChildTouchTest((touchinfo) => {
return { strategy: TouchTestStrategy.DEFAULT }
})
}
}
ts
点击下方空白区域后拖动,List不会滑动;点击Button按钮,Button会响应onClick事件。