父子组件嵌套滚动发生手势冲突,父组件有机制可以干预子组件的手势响应。下面例子介绍了如何使用手势拦截增强,在外层Scroll组件的shouldBuiltInRecognizerParallelWith和onGestureRecognizerJudgeBegin回调中,动态控制内外层Scroll手势事件的滚动。1 首先在父组件Scroll的shouldBuiltInRecognizerParallelWith方法中收集需做并行处理的手势。下面示例代码中收集到了子组件的手势识别器childRecognizer,使其和父组件的手势识别器currentRecognizer并行处理。2 调用onGestureRecognizerJudgeBegin方法,判断滚动组件是否滑动划到顶部或者底部,做业务逻辑处理,通过动态控制手势识别器是否可用,来决定并行处理器的childRecognizer和currentRecognizer是否可用。@Entry @Component struct GesturesConflictScene7 { scroller: Scroller = new Scroller(); scroller2: Scroller = new Scroller(); private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; private childRecognizer: GestureRecognizer = new GestureRecognizer(); private currentRecognizer: GestureRecognizer = new GestureRecognizer(); build() { Stack({ alignContent: Alignment.TopStart }) { Scroll(this.scroller) { // 外部滚动容器 Column() { Text('Scroll Area') .width('100%') .height(150) .backgroundColor(0xFFFFFF) .borderRadius(15) .fontSize(16) .textAlign(TextAlign.Center) .margin({ top: 10 }) Scroll(this.scroller2) { // 内部滚动容器 Column() { Text('Scroll Area2') .width('100%') .height(150) .backgroundColor(0xFFFFFF) .borderRadius(15) .fontSize(16) .textAlign(TextAlign.Center) .margin({ top: 10 }) Column() { ForEach(this.arr, (item: number) => { Text(item.toString()) .width('100%') .height(200) .backgroundColor(0xFFFFFF) .borderRadius(15) .fontSize(20) .textAlign(TextAlign.Center) .margin({ top: 10 }) }, (item: string) => item) } .width('100%') } } .id('innerScroll') .scrollBar(BarState.Off) // 滚动条常驻显示 .width('100%') .height(800) }.width('100%') } .id('outerScroll') .height(600) .scrollBar(BarState.Off) // 滚动条常驻显示 .shouldBuiltInRecognizerParallelWith((current: GestureRecognizer, others: Array<GestureRecognizer>) => { for (let i = 0; i < others.length; i++) { let target = others[i].getEventTargetInfo(); if (target) { if (target.getId() === 'innerScroll' && others[i].isBuiltIn() && others[i].getType() === GestureControl.GestureType.PAN_GESTURE) { // 找到将要组成并行手势的识别器 this.currentRecognizer = current; // 保存当前组件的识别器 this.childRecognizer = others[i]; // 保存将要组成并行手势的识别器 return others[i]; // 返回将要组成并行手势的识别器 } } } return undefined; }) .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer, others: Array<GestureRecognizer>) => { // 在识别器即将要成功时,根据当前组件状态,设置识别器使能状态 if (current) { let target = current.getEventTargetInfo(); if (target) { if (target.getId() === 'outerScroll' && current.isBuiltIn() && current.getType() === GestureControl.GestureType.PAN_GESTURE) { if (others) { for (let i = 0; i < others.length; i++) { let target = others[i].getEventTargetInfo() as ScrollableTargetInfo; if (target instanceof ScrollableTargetInfo && target.getId() == 'innerScroll') { // 找到响应链上对应并行的识别器 let panEvent = event as PanGestureEvent; if (target.isEnd()) { // isEnd返回当前滚动类容器组件是否在底部 根据当前组件状态以及移动方向动态控制识别器使能状态 if (panEvent && panEvent.offsetY < 0) { this.childRecognizer.setEnabled(false) // 到底上拉 this.currentRecognizer.setEnabled(true) } else { this.childRecognizer.setEnabled(true) this.currentRecognizer.setEnabled(false) } } else if (target.isBegin()) { if (panEvent.offsetY > 0) { // 开始的时候下拉 this.childRecognizer.setEnabled(false) this.currentRecognizer.setEnabled(true) } else { this.childRecognizer.setEnabled(true) this.currentRecognizer.setEnabled(false) } } else { this.childRecognizer.setEnabled(true) this.currentRecognizer.setEnabled(false) } } } } } } } return GestureJudgeResult.CONTINUE; }) } .width('100%') .height('100%') .backgroundColor(0xF1F3F5) .padding(12) } }本文参与了 【 HarmonyOS NEXT 技术问答冲榜,等你来战!】欢迎正在阅读的你也加入。
父子组件嵌套滚动发生手势冲突,父组件有机制可以干预子组件的手势响应。下面例子介绍了如何使用手势拦截增强,在外层Scroll组件的shouldBuiltInRecognizerParallelWith和onGestureRecognizerJudgeBegin回调中,动态控制内外层Scroll手势事件的滚动。
1 首先在父组件Scroll的shouldBuiltInRecognizerParallelWith方法中收集需做并行处理的手势。下面示例代码中收集到了子组件的手势识别器childRecognizer,使其和父组件的手势识别器currentRecognizer并行处理。
2 调用onGestureRecognizerJudgeBegin方法,判断滚动组件是否滑动划到顶部或者底部,做业务逻辑处理,通过动态控制手势识别器是否可用,来决定并行处理器的childRecognizer和currentRecognizer是否可用。
本文参与了 【 HarmonyOS NEXT 技术问答冲榜,等你来战!】欢迎正在阅读的你也加入。