Gesture Detector isn't working - why not?
print or Navigator not working
GestureDetector(
onTap: () {
... ;
},
child: Container(
color: Colors.white,
width: 170,
height: 60,
child:...
),
),
Often times, this is because your GestureDetector is a child of another Widget that has an onTap property. For example, if you give an ElevatedButton a child of GestureDetector, this GestureDetector's onTap is never reached, due to the ElevatedButton overruling its onTap property.
Related
As far as I know, due to this question Flutter AbsorbPointer vs IgnorePointer difference , AbsorbPointer will absorb tap event and other widgets below it will not receive tap event, but when I use AbsorbPointer like this. it still pass tap event to its parent:
GestureDetector(
onTap: () {
print('123'); // This still call when I tap on red container
},
child: Container(
color: Colors.green,
width: 300,
height: 300,
child: Center(
child: AbsorbPointer(
absorbing: true,
child: GestureDetector(
onTap: () {
print('567');
},
child: Container(
color: Colors.red,
width: 100,
height: 100,
),
),
),
),
),
)
So my question is does AbsorbPointer only work with widget same level in Stack and doesn't work with its parent?
In your code absorbing property having true value. which means your red container is not clickable. so parent green container have tapped. Incase if you change absorbing property to false, red container can able to tap.
I have a stack containing a GestureDetector (which is the up-most layer and spans across the whole screen) and another widget (under it) that eventually has a ListView. The problem is that the global GestureDetector uses onHorizontalDrag which consumes the touch event. Instead, I want the ListView to consume that event only.
In short, is there a way to make the ListView take precedence over the GestureDetector without keeping some sort of a state? Note, the ListView is not a child/sub-child of the GestureDetector - they are on different branches within the widget tree.
I try out a stack with two GestureDetectors. It gives the highest preference to the GestureDetector which is placed last in the stack.
Example:
#override
Widget build(BuildContext context) {
return Stack(
children: [
GestureDetector(
onTap: () => {
print("gesture detector1 event fired"),
},
child: Container(
color: Colors.red,
height: 600,
width: 400,
),
),
GestureDetector(
onTap: () => {
print("gesture detector2 event fired"),
},
child: Container(
color: Colors.blue,
height: 200,
width: 400,
),
),
],
);
}
When you click on the blue color container "Gesture Detector 2 is fired", you click on the red color container then "Gesture Detector 1 is fired"
Refer this image
try adding behavior: HitTestBehavoir.translucent or HitTestBehavoir.deferToChild to the gestureture detector.
Wanna implement same functionality that is done here with images:
Flutter how to change image after onTap with Gesture Detector
Im using this package:
https://pub.dev/packages/flutter_svg/example
Even though I'm able to do this in IconButton, I need this in GestureDetector, not in IconButton, so just to be clear, need help how to implement SVG into GestureDetector not IconButton!
I'm able to get SVG rendered on the screen but can't figure it out how to implement it in GestureDetector, to render SVG on screen, Im doing it like this:
Expanded svgTest({double blackKeyWidth}) {
return Expanded(
child: Container(
child: IconButton(
icon: SvgPicture.asset(
'assets/images/1.svg',
fit: BoxFit.fill,
allowDrawingOutsideViewBox: true,
width: 500,
),
onPressed: null //do something,
),
),
);
}
Cant figure out how to implement SVG in GestureDetector, it can't go in as Image and Gesture Detector doesn't accept icon, or Im not doing it right.
Thank
If you want to change the image on the onTap method of the iconButton then you should have to change the path of the image in onTap method using setState
String imagePath = "assets/images/1.svg";
Expanded svgTest({double blackKeyWidth}) {
return Expanded(
child: Container(
child: IconButton(
icon: SvgPicture.asset(
'${imagePath}',
fit: BoxFit.fill,
allowDrawingOutsideViewBox: true,
width: 500,
),
onPressed: (){
setState(() {
imagePath = "assets/images/2.svg";
});
},
),
),
);
}
EDITED: (For Gesture Detector You Can Simply Wrap the SVG in it)
Replace the iconbutton with the GestureDetector and Add its onTap and onTapUp methods too.
GestureDetector(
onTap: () {
setState(() {
imagePath = "assets/images/2.svg";
});
},
onTapUp: (TapUpDetails tapUpDetails) {
setState(() {
imagePath = "assets/images/1.svg";
});
},
child: SvgPicture.asset(
'${imagePath}',
//fit: BoxFit.fill,
//allowDrawingOutsideViewBox: true,
//width: 500,
),
),
For More About GestureDetector and Flutter SVG Click Here
body: InkWell(
onTap: (){
print("optap");
},
child: Container(
width: 100,
height: 200,
color: Colors.red,
margin: EdgeInsets.fromLTRB(100, 200, 0, 0),
),
)
Container has a Margin. A InkWell wrapped the container, when I clicked the margin area of the container, the "onTap" method will call, why? I change the InkWell to GestureDector, it is ok.
An InkWell's splashes will not properly update to conform to changes if the size of its underlying Material, where the splashes are rendered, changes during animation. You should avoid using InkWells within Material widgets that are changing size.
use GestureDetector, for listening for gestures without ink splashes.
I got an issue with RaisedButton when using it inside a Positioned widget.
The problem is when I used RaisedButton inside Positioned widget, onPressed event didn't trigger when clicking on RaisedButton child, but when I clicked on another space of RaisedButton It worked.
Note that It works fine in normal situations and It happened when using RaisedButton inside Positioned widget.
here is my widget :
Positioned(
child: Center(
child: SizedBox(
width: 80,
height: 65,
child: RaisedButton(
padding: EdgeInsets.all(0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
color: Colors.green,
child: Icon(Icons.message, size: 50, color: Colors.white,),
// When I clicked on this icon, onPressed didn't triggered. but when I click on another space of button it triggered.
onPressed: () {
print('Hello world from onPressed');
},
),
),
),
top: -30,
left: 0,
right: 0,
)
what's your idea to fix this problem ?
The short answer is:
Flutter doesn't trigger push events for items that overlap the bounds of the stack (this is what you do when you set top to -30).
The reason behind this could be found here: Document that widgets in the overflow of stack do not respond to gestures
A possible solution for you is to move all the other items for 30.0 lower, so you can place the button inside the stack.
A solution to this problem is by wrapping the stack in a gesture detector and add what do you want to add in onpressed of the raised button in the ontap property of the gesture detector