Related
I wish to make my logo with rounded corners and did that with ClipRRect from Flutter. I also wanted a set height and width to my image. These together make it seem if the image was never rounded. When I remove the set height and width from the image, ClipRRect makes the image rounded, but very large.
The code:
body: Container(
padding: EdgeInsets.all(20),
child: Column(children: [
ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: Image.asset('assets/images/logo.png', width: 300, height: 150),
),
])));
Thank you, all help is appreciated.
Clear padding for the container and use fit property for the image widget.
Example
ClipRRect(
borderRadius: BorderRadius.circular(75.0),
child: Image.network(
'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80',
height: 150.0,
width: 150.0,
fit: BoxFit.cover,
),
),
Update for Container with column widget tree:
Container(
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(75.0),
child: Image.network(
'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80',
height: 150.0,
width: 150.0,
fit: BoxFit.cover,
),
),
],
),
),
I am new to Flutter and I like it but I am not comfortable building layouts.
I am working on an app that contains a ListView of Cards.
Each card is inside a Container and contains an image (with fixed height and width) and a text.
I am not able to place the image correctly inside the Card. I want the image to cover the width of box.
Thanks.
This is the code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
final title = 'MyApp';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: ListView(
children: <Widget>[
Container(
margin:EdgeInsets.all(8.0),
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
child: InkWell(
onTap: () => print("ciao"),
child: Column(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
),
child: Image.asset(
'img/britannia.jpg',
width: 300,
height: 150,
fit:BoxFit.fill
),
),
ListTile(
title: Text('Pub 1'),
subtitle: Text('Location 1'),
),
],
),
),
),
),
],
),
),
);
}
}
You need to add - crossAxisAlignment: CrossAxisAlignment.stretch, in Column so that children can take up horizontal space.
Working Code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
final title = 'MyApp';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: ListView(
children: <Widget>[
Container(
margin:EdgeInsets.all(8.0),
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
child: InkWell(
onTap: () => print("ciao"),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // add this
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
),
child: Image.network(
'https://placeimg.com/640/480/any',
// width: 300,
height: 150,
fit:BoxFit.fill
),
),
ListTile(
title: Text('Pub 1'),
subtitle: Text('Location 1'),
),
],
),
),
),
),
Container(
margin:EdgeInsets.all(8.0),
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
child: InkWell(
onTap: () => print("ciao"),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
),
child: Image.network(
'https://placeimg.com/640/480/any',
// width: 300,
height: 150,
fit:BoxFit.fill
),
),
ListTile(
title: Text('Pub 1'),
subtitle: Text('Location 1'),
),
],
),
),
),
),
Container(
margin:EdgeInsets.all(8.0),
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
child: InkWell(
onTap: () => print("ciao"),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
),
child: Image.network(
'https://placeimg.com/640/480/any',
// width: 300,
height: 150,
fit:BoxFit.fill
),
),
ListTile(
title: Text('Pub 1'),
subtitle: Text('Location 1'),
),
],
),
),
),
),
],
),
),
);
}
}
output:
I don't know how.. But this really worked to keep image with fixed size in container
Just add Alignment in container
Container(
height: double.infinity,
alignment: Alignment.center, // This is needed
child: Image.asset(
Constants.ASSETS_IMAGES + "logo.png",
fit: BoxFit.contain,
width: 300,
),
);
This worked for me
Image.network(imageUrl, fit: BoxFit.fitWidth,),
Put Image widget inside container and give alignment center to container and specific width-height to the image.
return Container(
alignment: Alignment.center,// use aligment
color: Color.fromRGBO(0, 96, 91, 1),
child: Image.asset('assets/images/splash_logo.png',
height: 150,
width: 150,
fit: BoxFit.cover),
);
Image.asset(
'assets/images/desert.jpg',
height: 150,
width: MediaQuery.of(context).size.width,
fit:BoxFit.cover
)
child: Container(
alignment: Alignment.center,// use aligment
child: Image.asset(
'assets/images/call.png',
height: 45,
width: 45,
fit: BoxFit.cover,
),
),
Use this if you want with border
Center(
child: Container(
margin: EdgeInsets.only(top: 75),
width: 120,
height: 120,
alignment: Alignment.center,
child: Image.asset(
"assets/images/call.png",
fit: BoxFit.cover,
height: 45,
width: 45,
),
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.all(new Radius.circular(120)),
border: new Border.all(
color: Colors.blue,
width: 4.0,
),
),
),
)
I used this and worked fine with me!
Container(
width: MediaQuery.of(context).size.width,
height: 175,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(YOUTUBE_THUMBNAIL_PART_ONE +
video.key +
YOUTUBE_THUMBNAIL_PART_TWO),
),
)),
What you want to do is probably use the size of the bigger container.
In that case your media should occupy the whole dedicate space:
return Container(
alignment: Alignment.center,
height: double.infinity,
width: double.infinity,
child: Image.asset(
'', //TODO fill path
height: double.infinity,
width: double.infinity,
fit: BoxFit.cover,
),
);
You can play with the fit value:
BoxFit.cover will cover the whole container
BoxFit.fitWidth will fit the width and eventually put horizontal white bars to fill the space
BoxFit.fitHeight will fit the height and eventually put vertical white bars to fill the space
If doable with the fit property, I let this very clear cheat sheet (chapter fit Property) detail everything: https://medium.com/jlouage/flutter-boxdecoration-cheat-sheet-72cedaa1ba20
All you need is fit property of Image class:
Image.asset(
'your_image_asset',
fit: BoxFit.fill, // Expands to fill parent (changes aspect ratio)
)
or
Image.asset(
'your_image_asset',
fit: BoxFit.cover, // Zooms the image (maintains aspect ratio)
)
I had the same problem, I just added in the Image.asset class the fit:BoxFit.fill after using the MediaQuery class to get the width of the screen**
Container(
child:Image.asset(link,fit: BoxFit.fill,)
width: screensize.width,
height: 150,
))
I'm trying to make a circular image box, but after using shape: Boxshape.circle, it is working properly on my current image. I'm sure that the shape property doesn't depend on the image pixel or any sort of thing.
I have this code:
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 40.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
height: 144.0,
width: 144.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.fill,
image: AssetImage('MY_IMAGE')
)
)
)
]
)
)
],
);
I have read about the Boxdecoration from this link: Flutter - BoxDecoration. I'm confident that the shape should work but in my case, it is not working.
This is the result which I'm getting right now:
Use a ClipRRect inside a SizedBox :
Container(
child: new SizedBox(
height: 144.0,
width: 144.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(72.0),
child: new Image.asset('MY_IMAGE'),
),
),
),
Try this code
Container(
color: Colors.amber,// this is just for detection, rounded or not
child: Center(
child: new Container(
height: 144.0,
width: 144.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(72),
image: DecorationImage(
fit: BoxFit.fill,
image: AssetImage('assets/img1.png')))),
),
)
Use the same code that you have posted in the question. But, instead of BoxFit.contain or BoxFit.fill, try using BoxFit.cover.
As it is mentioned in the comment by Mazin Ibrahim in the above answer, the actual height of your image must be less than the radius of the circular container, so even though the container is circular in shape you are not able to see it.
Check this link for more details.
For me it works using ClipOval in the child, and increasing a bit the image size with Transform.scale
Container(
decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(40))),
child: ClipOval(
child: Transform.scale(
scale: 1.6,
child: Image.asset(
"my asset image",
width: 80,
height: 80,
fit: BoxFit.cover,
),
),
),
)
For my case it worked like that -
Container(
height: (20.0),
width: (20.0),
decoration: const BoxDecoration(
shape: BoxShape.circle,
),
child: ClipOval(
child: SvgPicture.asset(
'assets/icons/$icon.svg',
fit: BoxFit.cover,
color: color,
),
),
)
I have tried these
1. DecorationImage
2. Image
3. CircleAvatar
I have used Stack as there will be a background image.
But I am not able to understand why the image is expanding like that.
I need a circular image for the profile pic.
If I use Column instead of ListView then the images doesn't expand like this ...but I need a ListView.
The code:-
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 80.0,
width: 80.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
image: AssetImage(Assets.cool),
fit: BoxFit.cover,
),
color: Colors.red,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 50.0,
width: 50.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image(
image: AssetImage(Assets.cool),
fit: BoxFit.cover,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: CircleAvatar(
radius: 50.0,
backgroundImage: AssetImage(Assets.cool),
),
)
],
)
],
),
);
}
From my understanding you want the image in a circle not a ellipse. You can achieve that by wrapping the items in your listview with a Row element.
return Scaffold(
body: Stack(
children: <Widget>[
ListView(
children: <Widget>[
// Wrap with a row
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 80.0,
width: 80.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
image: AssetImage("a.jpg"),
fit: BoxFit.cover,
),
color: Colors.red,
),
),
),
//...
],
),
],
)
],
),
);
To get a circular image, Just wrap all your widget of ListView in a Column widget and place the Column in ListView. You'll get a scrollable column.
ListView(
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 80.0,
width: 80.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
image: AssetImage(Assets.cool),
fit: BoxFit.cover,
),
color: Colors.red,
),
),
),
//.....
],
)
],
),s
Please let me know how to enable loading spinner for flutter CachedNetworkImageProvider. This works fine with CachedNetworkImage. But the problem is CachedNetworkImage is not a valid image provider.
Container(
width: 80.0,
height: 80.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: CachedNetworkImageProvider('https://pbs.twimg.com/profile_images/945853318273761280/0U40alJG_400x400.jpg'),
),
),
)
You can use imageBuilder property of CachedNetworkImage
CachedNetworkImage(
imageUrl: 'yourURL',
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
),
This way you can decorate your CachedNetworkImage like a Container
A little late but I followed this approach
https://flutter.dev/docs/cookbook/images/fading-in-images
Using Stack, Padding, and the Container should do it. The bad thing here is the CircularProgressIndicator running in the background but it's invisible for the user. The Image should be bigger than the CircularProgressIndicator.
An example here
Stack(
children: <Widget>[
Padding(padding: const EdgeInsets.only(left: 10, top: 15),
child: CircularProgressIndicator(),
),
Container(
width: 80.0,
height: 80.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: CachedNetworkImageProvider(
'https://www.seti.org/sites/default/files/styles/original/public/2019-09/Zork%20alien%20head%20PPR.jpg?itok=T7eTYzCZ'),
),
),
),
],
)
The purpose of the Padding is to be behind the Image, no matter where it is.
For small images like this I think it is better the FadeInImage
FadeInImage(image: CachedNetworkImageProvider(url),
fit: BoxFit.cover,
placeholder: MemoryImage(kTransparentImage),
)
I have achieved this to some extent by using AdvancedNetworkImage
The issue now I am facing is rounding of top left and right corners does not work in the below code.
new Column(
children: [
Container (
height: 250.0,
width : double.infinity,
margin: const EdgeInsets.only(top:20.0, left: 20.0, right:20.0),
child: TransitionToImage(
AdvancedNetworkImage(getImage(context, i), timeoutDuration: Duration(minutes: 1), useDiskCache: true),
// placeholder: CircularProgressIndicator(),
duration: Duration(milliseconds: 300),
fit: BoxFit.cover,
loadingWidget: const CircularProgressIndicator(),
placeholder: const Icon(Icons.refresh),
enableRefresh: true,
),
decoration: BoxDecoration(
borderRadius: new BorderRadius.only( topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0) ),
),
),
Container(
width: double.infinity,
margin: const EdgeInsets.only(bottom:20.0, left: 20.0, right:20.0),
padding: const EdgeInsets.all(10.0),
decoration: new BoxDecoration(
color: Colors.black,
borderRadius: new BorderRadius.only( bottomLeft: Radius.circular(10.0), bottomRight: Radius.circular(10.0) ),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black,
offset: Offset(0.0, -12.0),
blurRadius: 20.0,
),
],
),
// alignment: TextAlign.left,
child: new Text( getTitle(context, i), style: TextStyle( color: Colors.white, fontSize: 30.0,fontWeight: FontWeight.normal) ),
),
],
)
If anyone know the issue with rounding corners, please comment.