Prevent touch event from reaching to parent widget - flutter

In following example when FlatButton is clicked touch event is also propageted to InkWell, which displays ripple. Is there a way to disable this kind of behavior? So if touch is consumed by child widget it doesn't reach widget's parent?
InkWell(
onTap: () {},
child: Row(
children: <Widget>[
Text("Dummy text"),
FlatButton(onPressed: () {}, child: Text("Button"))
],
),
);

The event doesn't reach the parent widget. The flat button has that ripple effect by default. You can disable it setting the splashColor of the FlatButton to transparent. The same thing can be done to the InkWell.
Like this
InkWell(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () {},
child: Row(
children: <Widget>[
Text("Dummy text"),
FlatButton(
splashColor: Colors.transparent,
onPressed: () {}, child: Text("Button"))
],
),
);

I know it's a bit too late but if anyone is looking for the right answer. Here it is.
InkWell(
onTap: () {},
child: Row(
children: <Widget>[
Text("Dummy text"),
FlatButton(onPressed: () {
FocusScope.of(context).requestFocus();
}, child: Text("Button")),
],
),
);
FocusScope.of(context).requestFocus() will make the button request the focus so the InkWell doesn't show ripples.

Related

How to fit two button within a row ? Flutter

I am new to flutter and I was wondering if someone can help me with my row of buttons. They both work outside of the row but not within it. I have attached the code below please let me know if you can help or need more information.
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(Icons.edit),
)
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StudyPage(
title: 'Add a study',
selected: 0,
),
),
);
},
),
],
)
],
),
I little modified your (Row) code as follows and now it works.
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: const Icon(Icons.edit),
onPressed: () {},
),
FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StudyPage(
title: 'Add a study',
selected: 0,
),
),
);
},
),
]),
As far as I know, you can try this
Row(children:[
Expanded(
child:
IconButton(
icon: Icon(Icons.edit),
)),
Expanded(
child:
IconButton(
icon: Icon(Icons.edit),
)),
]);
if it solve your problem, kindly accept it as an answer so that others will get help
First. Expanded only work when place inside Colum/Row children.
Expanded will take all space of parent Colum/Row and expand Colum/Row size it possible.
If you want Colum/Row to max size, try add mainAxisSize: MainAxisSize.max to Colum/Row instead.
Second. Your code look like has error when floatingActionButton not is a Widget when you place in Colum/Row children, it is a props of Scaffold. Try to replace it by a valid button like IconButton/ElevatedButton/etc.... Your IconButton missing onPressed too.
Example:
Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded( // Place `Expanded` inside `Row`
child: ElevatedButton(
child: Text('First button'),
onPressed: () {}, // Every button need a callback
),
),
Expanded( // Place 2 `Expanded` mean: they try to get maximum size and they will have same size
child: ElevatedButton(
child: Text('Second button'),
onPressed: () {},
),
),
],
)

Flutter How to partially block touch event inside GestureDetector

I have a listview with every Item wrap inside a GestureDetector to be clickable, but is there a way to have a portion of the Item view to be not clickable? Thanks
GestureDetector(
onTap: () {
...
},
behavior: HitTestBehavior.opaque,
child: Column(
children: <Widget>[
child: SizedBox( height: 40,
child: Container(
color: Colors.green,
child: Text("Hello world"), // want to make the text area not clikable
),
),
someOtherWidgets...
],
),
Yes then you have to take particular item click and it should be blank in that case, Example InkWell click and child Text
InkWell(
onTap: () {
...
},
behavior: HitTestBehavior.opaque,
child: Column(
children: <Widget>[
child: SizedBox( height: 40,
child: Container(
color: Colors.green,
child: GestureDetector(
onTap: (){}
,
child:Text("PBX",style: TextStyle(fontSize: 15.0),)), // you can use like this text will be blank click
),
),
someOtherWidgets...
],
),

Flutter prevent click through widget

How can I make a clickable widget with a ripple and a button inside?
Here is the code I have:
Material(
child: InkWell(
onTap: () {},
child: Column(
children: <Widget>[
Text("this column is clickable"),
IconButton(
icon: Icon(Icons.airplanemode_active),
onPressed: () {},
),
]
)
)
),
When clicking on the Column, everything works fine, the ripple effect go behind the IconButton as expected. But when clicking on the IconButton, the onPressed trigger is called but it also activates the InkWell. Is there a way to prevent in from activation the InkWell?
Put Column widget inside GestureDetector and set excludeFromSemantics: true like the following:
Material(
child: Padding(
padding: const EdgeInsets.all(40.0),
child: InkWell(
onTap: () {},
child: GestureDetector(
excludeFromSemantics: true,
child: Column(
children: <Widget>[
Text("this column is clickable"),
IconButton(
icon: Icon(Icons.airplanemode_active),
onPressed: () {},
),
]
),
)
),
)
),
Its from this github post.

How to prevent ripple effect on surrounding InkWell when tapped on InkWell inside

Let's say that I have this widget:
Card(
child: InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(28.0),
child: RaisedButton(
child: Text('Test'),
onPressed: () {},
),
),
),
),
I would like to disable (prevent showing) ripple effect on Card/InkWell only when the RaisedButton is tapped, but to show it when the Card is tapped (i.e. outside the button). Is there any way to achieve this effect?
I think the generalized question can be: How to prevent ripple effect on surrounding InkWell when tapped on InkWell inside? If you take a look at the source code then you can see that RaisedButton has Material and InkWell widgets that cause ripple.
Here is the full sample code.
If you want a quick hack, check it out:
Container(
width: 180,
height: 120,
child: Stack(
children: <Widget>[
Card(
child: InkWell(
onTap: () {},
),
),
Center(
child: RaisedButton(
child: Text('Test'),
onPressed: () {},
),
)
],
),
)
You can handle the logic inside onHighlightChanged method;
Color _color;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Card(
child: InkWell(
splashColor: _color,
highlightColor: _color,
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(28.0),
child: RaisedButton(
onHighlightChanged: (value) {
if (value) {
setState(() => _color = Colors.white);
} else {
Timer(Duration(milliseconds: 200), () {
setState(() => _color = null);
});
}
},
child: Text('Test'),
onPressed: () {},
),
),
),
),
),
);
}
try this out https://dartpad.dev/7ff7f5756d93db2d4ed6a4b9a6d75208. I used hack with wrapping in InkWell the widget you want to surround with parent InkWell

Flutter - Container onPressed?

I have this container:
new Container(
width: 500.0,
padding: new EdgeInsets.fromLTRB(20.0, 40.0, 20.0, 40.0),
color: Colors.green,
child: new Column(
children: [
new Text("Ableitungen"),
]
),
),
When the user clicks on the Container, I want an onPressed() method to be fired (like it can be done with IconButton for example). How can I achieve this behaviour with Container?
I guess you can use GestureDetector widget like this:
new GestureDetector(
onTap: (){
print("Container clicked");
},
child: new Container(
width: 500.0,
padding: new EdgeInsets.fromLTRB(20.0, 40.0, 20.0, 40.0),
color: Colors.green,
child: new Column(
children: [
new Text("Ableitungen"),
]
),
)
);
Don't use GestureDetector, it doesn't show ripple effect. Use InkWell instead.
InkWell(
onTap: () {}, // Handle your callback
child: Ink(height: 100, width: 100, color: Colors.blue),
)
Output:
The simplest solution is to wrap the Container in a GestureRecognizer, but consider using an InkWell or FlatButton if you are building a Material design app. These widgets will show a visual splash response when touched.
The container itself doesn't have any click event, so to do that there are two ways
InkWell widget
GestureDetector
In Flutter, InkWell is a material widget that responds to touch action.
InkWell(
child: Container(......),
onTap: () {
print("Click event on Container");
},
);
GestureDetector is a widget that detects the gestures.
GestureDetector(
onTap: () {
print("Click event on Container");
},
child: Container(.......),
)
Difference
InkWell is a material widget and it can show you a Ripple Effect whenever a touch was received.
GestureDetector is more general-purpose, not only for touch but also for other gestures.
Heading
GestureDetector vs InkWell
You can use two widget
1) GestureDetector
GestureDetector(
onTap: (){
print("Container clicked");
},
child: new Container(child: ...)
);
This widget, doesn't have any effect.
2) InkWell
InkWell(
child: Container(......),
onTap: () {
print("Click event on Container");
},
);
This widget has animation effect.
Just wanted to add on to The Dumbfounds answer(accepted ans above)
If you are using GestureDetector or InkWell to handle the click of a group of icon and text, then use Icon widget instead of IconButton to display the icon as the onPressed method of IconButton will take over the onTap method of GestureDetector/InkWell and as a result the onTap then will only work if you click on the text.
Example -
#override
Widget build(BuildContext context) {
return Row(mainAxisSize: MainAxisSize.min, children: [
GestureDetector(
onTap: () {
_toggleFavorite();
},
child: Row(
children: [
Container(
padding: EdgeInsets.all(0.0),
child: _isFavorited ? Icon(Icons.star, color: Colors.red[500]) : Icon(Icons.star_border),
),
SizedBox(
width: 18.0,
child: Container(
child: Text('$_favoriteCount'),
),
)
],
),
)
]);
}
}
InkWell(
child: Container(
width: 500.0,
padding: new EdgeInsets.fromLTRB(20.0, 40.0, 20.0, 40.0),
color: Colors.green,
child: new Column(
children: [
new Text("Ableitungen"),
]
),
),
onTap: () {
print("Tapped on container");
},
);
User can make button of any widget using Inkwell and GestureDetector.
=====
InkWell(
onTap: () {
print("");
},
child: Container(......),
);
======
GestureDetector(
onTap: () {
print("");
},
child: Container(.......),
)
InkWell(
child: Container(......),
onTap: () {
print("Add your on tap event in this block");
},
);
Use InkWell it will provide you a nice material ripple effect.