为解决点击菜单区域外时事件穿透问题,当菜单显示时,在页面最外层组件上添加hitTestBehavior.Block属性以阻止事件传播。同时,在最外层组件的点击事件回调方法中加入一个if条件判断,判断是否是处于菜单显示的情况,若是则直接返回,不处理后面的点击逻辑。
import { PromptAction } from '@kit.ArkUI'; @Entry @Component struct BindContextMenuIndex { @State menuShow: boolean = false; @State flag: boolean = false; promptAction: PromptAction = new PromptAction(); @Builder menu() { Menu() { MenuItem({ startIcon: $r('app.media.startIcon'), content: '菜单1' }); MenuItem({ startIcon: $r('app.media.startIcon'), content: '菜单2' }); MenuItem({ startIcon: $r('app.media.startIcon'), content: '菜单3' }); }; } build() { Column() { Text('第一层') .height('150vp'); Column() { Text('第二层') .height('150vp'); Column() { Text('第三层的兄弟层1') .height('150vp'); } .width('100%') .backgroundColor('#0D5AF5') .onClick(() => { this.promptAction.showToast({ message: '第三层的兄弟层1' }); }) // 长按手势,将控制菜单显隐的值修改为true .gesture(LongPressGesture().onAction(() => { this.menuShow = true; this.flag = true; })) // 绑定菜单 .bindContextMenu(!!this.menuShow, this.menu(), { onDisappear: () => { this.menuShow = false; } }); Column() { Text('第三层的兄弟层2') .height('150vp'); } .width('100%') .backgroundColor('#0D85F5') .onClick(() => { this.promptAction.showToast({ message: '第三层的兄弟层2' }); }); } .width('100%') .height('100%') .backgroundColor('#65BA5F') .onClick(() => { this.promptAction.showToast({ message: '第二层' }); }); } .width('100%') .height('100%') .backgroundColor('#ECA724') .onClick(() => { console.info('onClick'); if (this.flag) { this.flag = false; return; } this.promptAction.showToast({ message: '第一层' }); }) // 阻止事件穿透 .hitTestBehavior( this.menuShow ? HitTestMode.Block : HitTestMode.Default ); } }