I'm trying to make a GestureDetector work inside a Stack with a Container on top of it but the onTap callback is never called.
As you can see, it doesn't work even with 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),
],
),
),
);
}
I know that it can be strange that I would want to capture tap event below another Widget but in my real case, the widget on top is transparent and sometimes has a gradient.
They both look the same and almost do the same thing, so what is difference between flutter InkWell vs GestureDetector? Generally speaking, GestureDetector provides more gesture control to detect almost every user interaction including dragging, swiping, pinching, etc.
Use GestureDetector's behavior property and pass HitTestBehavior. opaque to it, which recognizes entire screen and detects the tap when you tap anywhere on the screen.
OnTap of GestureDetector is not working for containers in stack. · Issue #23454 · flutter/flutter · GitHub Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community. By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement.
In the body of Scaffold (), we pass Center () and after that, we pass GestureDetector () as a child of it. We create a Container () and pass the color and text which is already passed the code.
Just make sure that your gesturedetector is not overlapped with other widgets that has color. stack [ gesturedetector, container, widgets... ] make sure that the container has no color because even transparent color can overlap the inputs.
GestureDetector In Flutter. When it comes to creating applications… | by Raksha Goswami | FlutterDevs W hen it comes to creating applications, you have to handle user reactions such as touch and drags. This makes your application interactional beneficially handle gestures, you need to listen to the gestures and greet them.
Ok guys, I think I found a solution myself. I hope that there exist a simpler solution but it works for my use. The problem I had was that the Stack widget doesn't pass the hit test to all children but only the first one that is hit. What I did is that I rewrote the hit detection algorithm used by the Stack's RenderBox. I really didn't intended to go this far and I'm still waiting for a better answer. Here is my code, use it at your own risk :
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With