当使用bindContextMenu为组件A配置长按菜单时,菜单弹出后,如果点击菜单区域外的任意位置可以关闭菜单,但组件A(或其他区域外的组件)的点击事件也会被触发。

为解决点击菜单区域外时事件穿透问题,当菜单显示时,在页面最外层组件上添加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
- );
- }
- }