Reputation: 4688
How do you create a button with an image using Flutter? It seems like the simplest thing to do, but the image does not fill the parent widget completely. This is what I have:
Container(child: ConstrainedBox(
constraints: BoxConstraints.expand(),
child: FlatButton(onPressed: null,
child: Image.asset('path/the_image.png'))))
I followed this post as guidance. My image looks like this:
Notice the padding around the PNG image - it's not in the code. Where does it come from? The PNG itself does not have canvas padding, so this must not be the correct technique.
All I need is a button with an image that fills the entire FlatButton
, or another widget I can add actions to, without distorting the image.
Upvotes: 62
Views: 160762
Reputation:
Place your image in a gestureDetector
like this:
GestureDetector(
onTap: () {},
child: Image.asset('path/the_image.png')
)
Upvotes: 4
Reputation: 135
If you have a rounded rectangle button then follow the below code
TextButton(
style: TextButton.styleFrom(
alignment: Alignment.topLeft,
backgroundColor: Colors.lightBlue,
minimumSize: const Size(double.infinity, 200),
padding: const EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
),
onPressed: () => null,
child: SizedBox(
height: 100,
width: 500,
child: Stack(
children: [
**Positioned(
top: 0,
left: 0,
right: 0,**
child: ClipRRect(
borderRadius: const BorderRadius.vertical(
top: Radius.circular(20),
),
child: Image.asset(
'assets/miniMartGrocery.png',
fit: BoxFit.cover,
),
),
),
Positioned(
top: 10,
left: screenSize.width * 0.84,
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(100),
color: Colors.white),
child: IconButton(
icon: Icon(
FontAwesomeIcons.flag,
),
onPressed: () => null,
),
))
],
),
),
),
Upvotes: 0
Reputation: 332
FlatButton(
onPressed: (){},
color: Colors.orange,
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
Image.asset(name),
Text("Add")
],
);
you can add icons and images
Upvotes: 1
Reputation: 71
Can use TextButton for this.
TextButton.icon(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white)),
onPressed: () {},
icon: Image.asset('path/the_image.png'),
label: Text(
'Button Text',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
)
Upvotes: 7
Reputation: 3668
I'm create own inkwell have triple anim that take child and callback onPress for non transparent background like image
class InkWellApp extends StatelessWidget {
final Function onTap;
final Widget child;
final EdgeInsets margin;
final BorderRadius borderRadius;
const InkWellApp(
{Key key,
this.onTap,
this.child,
this.borderRadius = BorderRadius.zero,
this.margin = EdgeInsets.zero})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: margin,
child: Stack(
children: [
child,
Positioned.fill(
child: Material(
color: Colors.transparent,
borderRadius: borderRadius,
child: InkWell(
borderRadius: borderRadius,
onTap: onTap,
),
),
),
],
),
);
}
}
and then you can use it inside app with any widget or image like this
InkWellApp(
onTap: (){
//your code here
},
child: yourWidget,
),
Note : borderRadius and margin is optional parameters
Upvotes: 1
Reputation: 268504
Screenshot:
Code:
InkWell(
onTap: () {}, // Handle your callback.
splashColor: Colors.brown.withOpacity(0.5),
child: Ink(
height: 100,
width: 100,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('your_image_asset'),
fit: BoxFit.cover,
),
),
),
)
Upvotes: 20
Reputation: 6090
Image button with Ripple Effect and Text on the bottom
(of course you can remove the text part and Stack)
Material(
elevation: 4.0,
clipBehavior: Clip.hardEdge,
color: Colors.transparent,
child: Stack(
alignment: Alignment.bottomCenter,
fit: StackFit.passthrough,
children: [
Ink.image(
image: AssetImage(imagePath),
fit: BoxFit.cover,
width: 120,
height: 120,
child: InkWell(onTap: () {}),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(label, style: const TextStyle(fontSize: 20)),
),
)
],
),
);
Upvotes: 0
Reputation: 77
GestureDetector(
onTap: () {print('click on edit');},
child: Image(
image: AssetImage('assets/images/icons/edit-button.png'),
fit: BoxFit.cover,
height: 20,
)
),
Upvotes: 6
Reputation: 19
you can do this easily using Stack
Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 3.6,
width: MediaQuery.of(context).size.width / 2.2,
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child:imageLoader1(img),
/* Image.asset(
"$img",
fit: BoxFit.cover,
),*/
),
),
Positioned(
right: -10.0,
bottom: 3.0,
child: RawMaterialButton(
onPressed: (){},
fillColor: Colors.white,
shape: CircleBorder(),
elevation: 4.0,
child: Padding(
padding: EdgeInsets.all(5),
child: Icon(
isFav
?Icons.favorite
:Icons.favorite_border,
color: Colors.red,
size: 17,
),
),
),
),
],
),
Upvotes: 0
Reputation: 3414
IconButton(
icon: Image.asset('path/the_image.png'),
iconSize: 50,
onPressed: () {},
)
Upvotes: 92
Reputation: 497
My opinion, the easier way and also most versatile is to use GestureDetector as it allows you to call different functions for different gestures like one tap, double-tap, long tap and so on.
GestureDetector(
onTap: () => _yourFunction('yourParameter'),
child: Image.asset('yourimagefolder/yourimage.png'),
),
Upvotes: 20
Reputation: 1842
Display image icon button with ripple effect over the image when pressed:
Material(
// needed
color: Colors.transparent,
child: InkWell(
onTap: () => myOnTap, // needed
child: Image.asset(
"assets/resize.png",
width: 22,
fit: BoxFit.cover,
),
),
)
Upvotes: 9
Reputation: 403
I think this should work as well. Just specify the padding for the FlatButton to zero.
Container(child: ConstrainedBox(
constraints: BoxConstraints.expand(),
child: FlatButton(
onPressed: null,
padding: EdgeInsets.all(0.0),
child: Image.asset('path/the_image.png'))))
Upvotes: 38
Reputation: 825
Having an image inside a FlatButton
might not fit your requirements, as it takes care of some styling ( like that padding ) on its own.
To have full control on your button aspect you might want to build a custom widget ( even a simple Container
with a custom BoxDecoration
to display the image ) and wrap it with a gesture recognizer to handle user interactions ( a simple tap, in your case ). The simplest implementation would use a GestureDetector
, but there are also other widgets, like InkWell
that renders a material design ripple over the tappable widget surface on tap.
Upvotes: 16