Listener(每日Flutter 小部件)
参考:https://www.lizenghai.com/archives/48633.html
const Listener({ Key key, this.onPointerDown, this.onPointerMove, this.onPointerEnter, this.onPointerExit, this.onPointerHover, this.onPointerUp, this.onPointerCancel, this.onPointerSignal, this.behavior = HitTestBehavior.deferToChild, Widget child, })
class _ListenerWidgetState extends State<ListenerWidget> { Offset offset = Offset(0.0, 0.0); String status = 'noPoint'; @override Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Listener( behavior: HitTestBehavior.opaque, child: ConstrainedBox( constraints: BoxConstraints.tight(Size(200, 200)), child: Center( child: Text('click me'), )), onPointerDown: (event) => print("onPointerDown}")), Text( 'Test', style: TextStyle(fontSize: 22.0), ), ], ), ); } }
behavior属性
behavior
表示命中测试(Hit Test)过程中的表现策略。它是一个枚举,提供了三个值,分别是HitTestBehavior.deferToChild
、HitTestBehavior.opaque
、HitTestBehavior.translucent
。
上面说到过,命中测试,就是看RenderBox
的hitTest
的返回值,如Listener
的hitTest
方法如下。
bool hitTest(BoxHitTestResult result, { Offset position }) { bool hitTarget = false; if (size.contains(position)) { hitTarget = hitTestChildren(result, position: position) || hitTestSelf(position); if (hitTarget || behavior == HitTestBehavior.translucent) result.add(BoxHitTestEntry(this, position)); } return hitTarget; } bool hitTestSelf(Offset position) => behavior == HitTestBehavior.opaque;
HitTestBehavior.deferToChild:Listener
是否命中测试,取决于子child
是否命中测试,这是默认behavior
的默认值。
HitTestBehavior.opaque:当Listener
的子child
没有命中测试时,该属性值保证hitTestSelf
返回true
,即保证Listener
所在区域能响应触摸事件。
HitTestBehavior.translucent:当Listener
的子child
没有命中测试时,并且hitTestSelf
返回false
时,该属性值可以保证Listener
所在的区域能响应触摸事件(加入到命中测试列表),但是hitTest
方法返回值还是false
,这不能改变。