How to add onClick on image.asset in flutter? - flutter

I am using three images on clicking which will navigate to other page so how should I use onClick on these images? My code is below:
Row(
children: [
Expanded(
child: Column(
children: <Widget>[
Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset('assets/cat.jpg',
width: 110.0, height: 110.0),
)),
Text(
'Tickets',
style:
TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),
)
],
),
),
Expanded(
child: Column(
children: <Widget>[
Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.asset('assets/cat.jpg',
width: 110.0, height: 110.0),
)),
Text(
'Buy Tickets',
style:
TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),
)
],
),
),
Expanded(
child: Column(
children: <Widget>[
Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.asset('assets/cat.jpg',
width: 110.0, height: 110.0),
)),
Text(
'Prizes',
style:
TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),
)
],
),
),
],
),
Expected : Adding an onClick on images
I used GestureDetector but it is throwing error so I need to know what I should use and how.

I read other answers and found that you were having issues with border, try this solution.
GestureDetector(
onTap: () {}, // Image tapped
child: Image.asset(
'assets/cat.jpg',
fit: BoxFit.cover, // Fixes border issues
width: 110.0,
height: 110.0,
),
)
If you want splash effects, then use Ink.image or Ink with decoration.
InkWell(
onTap: () {}, // Image tapped
splashColor: Colors.white10, // Splash color over image
child: Ink.image(
fit: BoxFit.cover, // Fixes border issues
width: 100,
height: 100,
image: AssetImage(
'assets/cat.jpg,
),
),
)

Material(
child: InkWell(
onTap: () {},
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset('assets/cat.jpg',
width: 110.0, height: 110.0),
),
),
)

You can use InkWell as show by #Murat Aslan.
And you can also use GestureDetector as shown below.
Material(
child: GestureDetector(
onTap: () {},
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset('assets/cat.jpg',
width: 110.0, height: 110.0),
),
),
),
)

An alternative is to use a FlatButton with an Image as a child:
FlatButton(
onPressed: () {
print('I got clicked');
},
child: Image.asset('images/ball1.png'),
),

To render a material splash during tap on image, use Ink.image
InkWell(
onTap: () {},
child: Ink.image(
image: AssetImage('assets/cat.jpg'),
// fit: BoxFit.cover,
width: 110,
height: 110,
),
)

Related

How can I make the white area transparent in this bottom navigation bar that I have implemented using stack in flutter

This is the code for the layout. I have built the layout using stack. A sizedbox with height 115 contains the stack which further contains the Row of icon buttons and the plus icon button. I have tried replacing the sizedbox with container and changing the color to transparent but to no avail. I don't really know from where the white area is being generated.
SizedBox(
height: 115,
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Container(
height: 75,
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
color: Color.fromRGBO(37, 37, 37, 1),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: List.generate(
5,
(index) {
if (index == 2) {
return const SizedBox(
height: 40,
width: 40,
);
}
return GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => nextScreens[index],
),
);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
iconsUrl[index],
height: 20,
width: 20,
),
Text(
titles[index],
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
)
],
),
);
},
),
),
),
Positioned(
child: GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SellPage(),
),
);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
width: 60,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: primaryColor,
border: Border.all(color: Colors.white, width: 3),
),
child: const Icon(
Icons.add,
size: 30,
color: Colors.white,
),
),
const Text(
"Sell",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
)
],
),
),
),
],
),
)
I assume that you have added the SizedBox inside a column. So the widgets inside the column is rendered just above the SizedBox. Remove the SizedBox from here and add it above the column in a stack like
SizedBox(
height: Mediaquery.of(context).size.height,
width : Mediaquery.of(context).size.width,
child: Stack(
children: [
Column(),
Positioned (
bottom: 0,
child: SizedBox(),//bottom bar here
)
]
)
may be it is because you have given height 115 to SizedBox

Flutter ripple effect for png or svg images

I am looking for someway to add ripple effect on the png or svg images in flutter, without covering the transparent parts in image.
I use this code to add ripple effect over an svg image:
Stack(
children: [
SvgPicture.asset(
R_Image.BACK,
width: 45,
height: 45,
fit: BoxFit.fill,
),
Positioned.fill(
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
),
),
),
],
)
And the result is as follows:
How to remove transparent parts of svg image from ripple effect?
In android, I use #android:id/mask for this purpose, but how to do that in flutter?
Try to wrap Stack with ClipRRect
ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Stack(
clipBehavior: Clip.none,
children: [
SvgPicture.asset(
R_Image.BACK,
width: 45,
height: 45,
fit: BoxFit.fill,
),
Positioned.fill(
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
),
),
),
],
),
),
Try this
body: new Center(
child: new Container(
child: new Material(
child: new InkWell(
onTap: (){print("tapped");},
child: new Container(
width: 100.0,
height: 100.0,
),
),
color: Colors.transparent,
),
color: Colors.orange,
),
),

Inkwell does not appear in custom button

When the sized box tapped, the ripple effect should happen on top of the widget. But it does not appear. The sized box appears, but ripple effect is not.
Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
width: widget.width,
height: widget.height,
child: Material(color: Colors.yellow, child: widget.icon
),
),
SizedBox(
width: widget.width,
height: widget.height,
child: InkWell(
borderRadius: BorderRadius.circular(25),
splashColor: Colors.purple,
onTap: () {}),
),
],
),
]);
EDIT: Wrapped the whole stack with the inkwell but still ripple does not appear.
InkWell(
borderRadius: BorderRadius.circular(25),
splashColor: Colors.purple,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
width: widget.width,
height: widget.height,
child: Material(color: Colors.yellow, child: widget.icon
),
Add InkWell above icon that will give a ripple effect
Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
height: 48,
width: 48,
child: Material(
color: Colors.yellow,
child: InkWell(
splashColor: Colors.purple,
onTap: () {},
child: const Icon(Icons.add),
),
),
),
],
),
OR
Material(
color: Colors.yellow,
child: InkWell(
splashColor: Colors.purple,
onTap: () {},
child: Container(
color: Colors.transparent,
height: 80,
width: 80,
child: Icon(Icons.add),
),
),
),
Output:
You must put the sized box as child of inkwell (or even move the complete stack into the inkwell child).
Inkwell is applied to its children.
InkWell(
borderRadius: BorderRadius.circular(25),
splashColor: Colors.purple,
onTap: () {
print('HEY');
},
child: SizedBox(
width: widget.width,
height: widget.height,
),
),
add onTap(){} to the inkWell, even if its not used. I think this fixes it, haven't tried it out tho. Also try wrapping the InkWell with a Material widget.

Flutter container width inside MaterialButton

I am trying for hours to set my container width to its parent, which is a MaterialButton. I want the container to fill the entire width of the MaterialButton.
I tried to set the container width to "double.infitiy" or to "MediaQuery.of(context).size.width". Also played with "Expanded" etc. None of it worked. Not sure what I am doing wrong, thanks.
#override
Widget build(BuildContext context) {
return Material(
**child: MaterialButton(
minWidth: MediaQuery.of(context).size.width,
onPressed: onPressed,
child: Container(
width: double.infinity,**
margin: EdgeInsets.all(8.0),
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.greenAccent,
borderRadius: BorderRadius.circular(10.0)),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(text),
SizedBox(
height: 8.0,
),
SvgPicture.asset(
'images/medaillen.svg',
width: 80,
),
SizedBox(
height: 15.0,
),
Text(
textTopThree,
maxLines: 3,
),
],
),
),
),
);
I recommend you to replace the Material Button with InkWell, you can wrap any widget and get the onTap.
This should work:
InkWell(
onTap: () {},
child: Container(
width: double.infinity,
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.greenAccent,
borderRadius: BorderRadius.circular(10.0),
),
child: Column(
children: [
Text('Button Text'),
SizedBox(
height: 8.0,
),
Image.asset(
'images/medaillen.svg',
width: 80,
),
SizedBox(
height: 15.0,
),
Text(
'textTopThree',
maxLines: 3,
),
],
),
),
),
If for some reason you need to use MaterialButton, then you should delete the Container and use the properties of the Material Button, like this:
MaterialButton(
onPressed: () {},
color: Colors.greenAccent,
minWidth: double.infinity,
padding: EdgeInsets.all(8.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
child: Column(
children: [
SizedBox(
height: 8.0,
),
Text('Button Text'),
SizedBox(
height: 8.0,
),
Image.asset(
'images/medaillen.svg',
width: 80,
),
SizedBox(
height: 15.0,
),
Text(
'textTopThree',
maxLines: 3,
),
SizedBox(
height: 8.0,
),
],
),
),

image's corner in flutter

I am working in this app and I have a problem first the pic doesn't take the all size of the clipRRect, then I used the Ink.Image and the BoxFit.fitHeight, it okay but now the pic doesnt take the radius of the clipRRect..
sorry for my weak english, here is the code and screenshoot for the app.
please check the pics its in link.
thanks alot.
Widget foodCard() {
return Padding(
padding: EdgeInsets.all(10.0),
child: Container(
child: FittedBox(
child: Material(
color: Colors.white,
elevation:8.0 ,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
),
child: Row(children: [
Container(
width: 250, height: 250,
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0)),
child: Ink.image(
height: 200,
fit: BoxFit.fitHeight,
alignment: Alignment.topLeft,
image: NetworkImage(
"https://images-gmi-pmc.edge-generalmills.com/087d17eb-500e-4b26-abd1-4f9ffa96a2c6.jpg"
)),)
),
Container(
child: Padding(padding: const EdgeInsets.all(8.0),
child: Column(children: [
Text("Recipe 1",
style: TextStyle(color: Colors.black),),
Text("Some data"),
ButtonBar(children: <Widget>[
FlatButton(
child: Text('Like'),
color: Colors.deepPurple,
onPressed: () {},
),
FlatButton(
child: Text('Dislike'),
color: Colors.deepPurple,
onPressed: () {},
),
],)
]),)
)
],)
)
),
));
}
before using fitbox.fithieght
after using it
I want the picture to be like this
copy and paste this Widget.
Padding(
padding: const EdgeInsets.all(16.0),
child: Material(
color: Colors.white,
elevation: 8.0,
shadowColor: Colors.blueGrey,
borderRadius: BorderRadius.all(Radius.circular(20.0)),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
child: FittedBox(
child: Material(
color: Colors.white,
elevation: 8.0,
shadowColor: Colors.blueGrey,
child: Row(
children: [
Container(
width: 250,
height: 250,
child: Ink.image(
height: 200,
fit: BoxFit.fitHeight,
alignment: Alignment.topLeft,
image: NetworkImage(
"https://images-gmi-pmc.edge-generalmills.com/087d17eb-500e-4b26-abd1-4f9ffa96a2c6.jpg"))),
Container(
padding: const EdgeInsets.all(8.0),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(children: [
Text(
"Recipe 1",
style: TextStyle(color: Colors.black),
),
Text("Some data"),
ButtonBar(
children: <Widget>[
FlatButton(
child: Text('Like'),
color: Colors.deepPurple,
onPressed: () {},
),
FlatButton(
child: Text('Dislike'),
color: Colors.deepPurple,
onPressed: () {},
),
],
)
]),
))
],
)))),
),
)