Flutter prevent click through widget - flutter

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.

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: () {},
),
),
],
)

Adding buttons to the bottom of the listTile

I am trying to look for an example in flutter in which there could be buttons on the bottom part of the ListTile. I have the below code, but somehow I am not able to add buttons in the bottom of the cell , I want to add 3 buttons , similar to the image shared
ListTile(title: Text("ListTile"),
subtitle: Text("Sample Subtitle. \nSubtitle line 3"),
trailing: Icon(Icons.home),
leading: Icon(Icons.add_box),
isThreeLine: true,
onTap: (){
print("On Tap is fired");
},
)
you can use a column inside your subtitle like this:
ListTile(
title: Text('title'),
subtitle: Column(
children: <Widget>[
Text('inside column'),
FlatButton(child: Text('button'), onPressed: () {})
],
),
),
preview on code pen
Try A Column with 2 Rows in your subtitle.
subtitle: Column(
children: <Widget>[
Container(height: 50, color: Colors.red, child: Row()),
Container(
child: Row(
children: <Widget>[
FlatButton(
child: Text("btn1"),
onPressed: () {},
),
FlatButton(
child: Text("btn2"),
onPressed: () {},
),
FlatButton(
child: Text("btn3"),
onPressed: () {},
),
],
))
],
),
You can use, ButtonBar
ButtonBar(children: [
FlatButton(
child: Text("Initialised Love"),
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...
],
),

Prevent touch event from reaching to parent widget

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.

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