Flutter中GestureDetector的onTap配合PopupMenuButton使用时无法触发问题
问题根因
PopupMenuButton 内部自身实现了点击事件逻辑用于弹出菜单,会消费掉触摸事件流,导致外层包裹的 GestureDetector 无法稳定接收点击事件,所以出现 onTapDown 时而触发时而失效的问题。
最优解决方案
直接使用 PopupMenuButton 原生提供的onOpened回调,该回调会在用户点击按钮、菜单弹出时立即触发,完全匹配点击切换箭头的需求,不需要额外嵌套手势组件,修改后代码如下:
Widget build(BuildContext context) { Get.find<HomeController>(); return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, title: Obx( () => PopupMenuButton<String>( offset: Offset(0, 38), shape: TooltipShape(), // 新增onOpened回调,点击弹出时切换箭头为向上状态 onOpened: () { controller.handlePopupMenuArrowIcon(); }, // 菜单取消关闭时切回箭头向下状态 onCanceled: () { controller.handlePopupMenuArrowIcon(); }, onSelected: (String where) { controller.changeLocation(where); // 选中后菜单关闭,切回箭头向下状态 controller.handlePopupMenuArrowIcon(); }, itemBuilder: (BuildContext context) { return [ PopupMenuItem(value: 'ara', child: Text('아라동')), PopupMenuItem(value: 'ora', child: Text('오라동')), PopupMenuItem( value: 'setting_neighborhood', child: Text('내 동네 설정하기'), ), ]; }, child: Row( children: [ Text( controller.locationTypeToString[ controller.currentLocation.value]!, style: TextStyle( color: Colors.black, ), ), controller.openOtherLocal.value ? Icon( Icons.keyboard_arrow_up_rounded, color: Colors.black, ) : Icon( Icons.keyboard_arrow_down_rounded, color: Colors.black, ), ], ), ), ), elevation: 1.0, ...
替代方案(必须使用手势检测时)
如果有特殊场景需要自行监听触摸事件,可以改用Listener组件包裹PopupMenuButton,Listener监听的是原始指针事件,不会被内部组件消费,可以稳定触发:
Listener( onPointerDown: (event) { print('tap'); print(event.position.dx); controller.handlePopupMenuArrowIcon(); }, child: PopupMenuButton<String>( // 原有PopupMenuButton配置不变 ), )
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

