Line data Source code
1 : import 'package:flutter/rendering.dart'; 2 : import 'package:flutter/widgets.dart' as widget; 3 : 4 : /// The `Stack` widget has limited hit test when child is overflow with 5 : /// `Positioned`. This behavior is intentional. For more detail refer to 6 : /// the bug report: [Document that widgets in the overflow of stack do not 7 : /// respond to gestures](https://github.com/flutter/flutter/issues/19445). 8 : /// 9 : /// The optional way to enable the hit test is define a new Stack and remove 10 : /// the size checking when teh Stack instance is overflow enable. 11 : /// 12 : class Stack extends widget.Stack { 13 1 : Stack({ 14 : widget.Key key, 15 : AlignmentGeometry alignment = AlignmentDirectional.topStart, 16 : TextDirection textDirection, 17 : StackFit fit = StackFit.loose, 18 : Overflow overflow = Overflow.clip, 19 : List<widget.Widget> children = const <widget.Widget>[], 20 1 : }) : super( 21 : key: key, 22 : alignment: alignment, 23 : textDirection: textDirection, 24 : fit: fit, 25 : overflow: overflow, 26 : children: children); 27 : 28 1 : @override 29 : RenderStack createRenderObject(widget.BuildContext context) { 30 1 : return _RenderStack( 31 1 : alignment: alignment, 32 2 : textDirection: textDirection ?? widget.Directionality.of(context), 33 1 : fit: fit, 34 1 : overflow: overflow, 35 : ); 36 : } 37 : } 38 : 39 : /// Enable overflow hitTest 40 : class _RenderStack extends RenderStack { 41 : Overflow overflow; 42 : 43 1 : _RenderStack({ 44 : List<RenderBox> children, 45 : AlignmentGeometry alignment = AlignmentDirectional.topStart, 46 : TextDirection textDirection, 47 : StackFit fit = StackFit.loose, 48 : this.overflow = Overflow.clip, 49 1 : }) : super( 50 : children: children, 51 : alignment: alignment, 52 : textDirection: textDirection, 53 : fit: fit, 54 : overflow: overflow); 55 : 56 1 : @override 57 : bool hitTest(BoxHitTestResult result, {Offset position}) { 58 2 : if (overflow == Overflow.visible || size.contains(position)) { 59 1 : if (hitTestChildren(result, position: position) || 60 1 : hitTestSelf(position)) { 61 2 : result.add(BoxHitTestEntry(this, position)); 62 : return true; 63 : } 64 : } 65 : return false; 66 : } 67 : }