Flutter GestureDetector包裹TextFormField时onTap不生效但onDoubleTap正常
问题原因
TextFormField默认会优先消费单点击手势,即便处于readOnly状态,单点击事件也会被它自身拦截,导致外层GestureDetector的onTap无法获取到手势事件。而TextFormField没有默认处理双击手势,所以双击事件可以正常冒泡到外层被捕获。- 修改
GestureDetector的behaviour属性无效,是因为该属性仅能处理同层级组件的手势冲突,无法覆盖子组件主动消费手势的场景。
解决方案
直接使用TextFormField自带的onTap回调处理点击逻辑即可,不需要在外层包裹GestureDetector,修改后TodoItem的title部分代码如下:
title: TextFormField( focusNode: _focusNode, initialValue: widget.title, // 直接用组件自带的onTap处理逻辑 onTap: () { print('tapped'); setState(() { isActive = !isActive; }); }, decoration: InputDecoration( hintText: widget.title, border: isActive ? UnderlineInputBorder( borderSide: BorderSide( width: 5, style: BorderStyle.solid, color: Colors.black)) : InputBorder.none), readOnly: !isActive, style: TextStyle(fontSize: 20), ),
如果需要在进入编辑状态后,再次点击标题不切换状态,只需要加个简单的判断:
onTap: () { if (isActive) return; print('tapped'); setState(() { isActive = true; }); },
可选替代方案
如果确实需要在外层监听手势事件,可以用Listener组件替代GestureDetector,它会直接监听原始指针按下事件,不受子组件消费手势的影响:
title: Listener( onPointerDown: (event) { print('tapped'); setState(() { isActive = !isActive; }); }, child: TextFormField( focusNode: _focusNode, initialValue: widget.title, decoration: InputDecoration( hintText: widget.title, border: isActive ? UnderlineInputBorder( borderSide: BorderSide( width: 5, style: BorderStyle.solid, color: Colors.black)) : InputBorder.none), readOnly: !isActive, style: TextStyle(fontSize: 20), ), ),
内容的提问来源于stack exchange,提问作者Yoofi Brown-Pobee
相关产品推荐
相关产品推荐

