Flutter - InkWell why affect on Margin area of container - flutter

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.

Related

Inkwell changes widget background color to the splash color, Flutter

Inkwell changes my widget background color to the splash color after doing a fast double tap directly after a tap, the splash starts to get bigger slowly until it fills the widget container, and then it stays as the widget's background color.
To activate this problem, just set onDoubleTap function for the inkwell and perform a tap on the widget then after half a second, perform a double tap on that widget, you will see the splash getting bigger and bigger slowly until it fills the container and then stay there.
This is how the widget background color should be
after double tap, after half a second of a tap, the splash starts to get bigger slowly
the splash fills the container and then stays there as the background of the widget even after hover on the widget again
even if you perform this again, the splash color gets darker as I believe that because of the adding up of two splash with opacity .8
Video to show the problem:
https://youtu.be/s9pOIeVE2ck
The question is how to stop this unexpected effect.
#override
Widget build(BuildContext context) {
return Container(
height: height,
width: width,
decoration: decoration,
alignment: alignment,
margin: margin,
child: Material(
borderRadius: BorderRadius.circular(borderRadius),
clipBehavior: Clip.hardEdge,
color: Colors.transparent,
shape: shapeBorder,
child: InkWell(
highlightColor: Colors.yellow.withOpacity(0.3),
splashColor: Colors.red.withOpacity(0.8),
focusColor: Colors.green.withOpacity(0.0),
hoverColor: Colors.blue.withOpacity(0.8),
onTap: onTap,
onDoubleTap: onDoubleTap,
onLongPress: onLongPress,
onTapCancel: () {
print('tap cancel');
},
canRequestFocus: false,
enableFeedback: false,
borderRadius: BorderRadius.circular(borderRadius),
child: Container(
padding: surroundInkEdge ?? EdgeInsets.all(borderRadius),
height: height,
width: width,
alignment: alignment,
child: child),
),
),
);
}
This is a known bug on all stable versions of Flutter up to the latest version 3.0.5 at the time of this writing. It has been already fixed on master branch tough.
The problem is with the onDoubleTab property. If you don't actually need to listen to it just remove it and all works fine.

Flutter: child button filling container size with explicit size

I'm trying to have a button nested in a container with a specific background color. I'm setting the height on the Container and on the MaterialButton nested within. I would expect the MaterialButton to maintain it's height of 40, while in the container of height 100. Instead, the MaterialButton is stretch to the height and width of the container.
Container(
color: lightBackground,
height: 100,
width: double.infinity,
child: MaterialButton(
height: 40,
child: Text('Hi'),
color: primaryColor,
onPressed: () {},
))
Anyone know how to get round this? Thanks.
The simple solution is to set alignment: Alignment.center for the Container, or wrap the Button with a Center widget.
For example:
Container(
height: 100,
alignment: Alignment.center,
child: ...
)
The long explanation has to do with Flutter Layout Constraints. You can read more about it at the official doc here.

Why isn't GestureDetector working in flutter?

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.

Gesture Detector Precedence

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.

Using RaisedButton widget inside Positioned widget issue

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