我正在尝试使GestureDetector在堆栈中工作,并在其上面放置一个容器,但是从未调用过onTap回调。
如您所见,即使使用HitTestBehavior.translucent
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: <Widget>[
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
print('tap');
},
child: Container(color: Colors.blue),
),
Container(color: Colors.white),
],
),
),
);
}
我知道我想在另一个小部件下面捕获轻敲事件可能很奇怪,但在我的实际情况下,顶部的小部件是透明的,有时会有渐变。
答案 0 :(得分:1)
此解决方案非常简单,不使用任何技巧或技巧!只需使用flutter小部件:
您可以用Container
包裹顶部小部件(在这种情况下为白色IgnorePointer
),并将ignoring
属性设置为true
。
Stack(
children:[
(...your down widget which should handle the tap...)
IgnorePointer(
ignoring:true,
child: (... your top widget which must be transparent to any tap ...)
)
]
)
然后,您的顶部小部件对任何水龙头都变得透明,并且水龙头将被顶部小部件下方的最顶部小部件捕获,而不被IgnorePointer
和ignoring:true
包裹。
例如,您可能对代码进行很少的更改即可达到所需的结果,例如:
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: <Widget>[
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
print('tap');
},
child: Container(color: Colors.blue),
),
IgnorePointer(ignoring:true,child:Container(color: Colors.white)),
],
),
),
);
}
有关更多信息,请访问the official help page on flutter.dev。
答案 1 :(得分:0)
您用一个完整的蓝色容器制作了一个容器(白色),因此,触摸它时,如果要管理它的触摸(白色容器),就放弃它(白色容器)还要在上面放置一个手势检测器。
一种简单的方法来测试将白色容器与蓝色容器反转的问题,并且会看到“轻击”的发生
这很好用:
Scaffold(
body: Container(
child: Stack(
children: <Widget>[
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
print('tap on white ');
},
child:
Container(color: Colors.white)),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
print('tap on blue');
},
child:
SizedBox(
height: 500,
child: Container(color: Colors.blue),
)
),
],
),
),
);
答案 2 :(得分:0)
好的,我想我自己找到了解决方案。我希望有一个更简单的解决方案,但对我有用。我遇到的问题是,堆栈小部件不会通过命中测试给所有孩子,而只能通过第一个被命中的孩子。我所做的是重新编写了Stack的RenderBox使用的命中检测算法。我真的不打算走这么远,我仍在等待更好的答案。这是我的代码,使用风险自负:
class CustomStack extends Stack {
CustomStack({children}) : super(children: children);
@override
CustomRenderStack createRenderObject(BuildContext context) {
return CustomRenderStack(
alignment: alignment,
textDirection: textDirection ?? Directionality.of(context),
fit: fit,
overflow: overflow,
);
}
}
class CustomRenderStack extends RenderStack {
CustomRenderStack({alignment, textDirection, fit, overflow})
: super(
alignment: alignment,
textDirection: textDirection,
fit: fit,
overflow: overflow);
@override
bool hitTestChildren(BoxHitTestResult result, {Offset position}) {
var stackHit = false;
final children = getChildrenAsList();
for (var child in children) {
final StackParentData childParentData = child.parentData;
final childHit = result.addWithPaintOffset(
offset: childParentData.offset,
position: position,
hitTest: (BoxHitTestResult result, Offset transformed) {
assert(transformed == position - childParentData.offset);
return child.hitTest(result, position: transformed);
},
);
if (childHit) stackHit = true;
}
return stackHit;
}
}