Flutter Network Image does not fit in Circular Avatar - image
I am trying to retrieve bunch of images from an api. I want the images to be displayed in Circular form so I am using CircleAvatar Widget, but I keep getting images in square format.
Here is a screenshot of images
Here is the code I am using
ListTile(leading: CircleAvatar(child: Image.network("${snapshot.data.hitsList[index].previewUrl}",fit: BoxFit.scaleDown,)),),
I tryied using all the properties of BoxFit like cover, contain,fitWidth,fitHeight etc but none of them works.
This Will Work : You need to use backgroundImage:property in order to fit it in Circle.
CircleAvatar(
radius: 30.0,
backgroundImage:
NetworkImage("${snapshot.data.hitsList[index].previewUrl}"),
backgroundColor: Colors.transparent,
)
To Check with Dummy Placeholder:
CircleAvatar(
radius: 30.0,
backgroundImage:
NetworkImage('https://via.placeholder.com/150'),
backgroundColor: Colors.transparent,
)
Had a similar problem in the AppBar actions widget list.
This worked for me:
CircleAvatar(
radius: 18,
child: ClipOval(
child: Image.network(
'image-url',
),
),
),
If you don't want to use CircleAvatar, here is how you can do it.
ClipOval(
child: Image.network(
'https://via.placeholder.com/150',
width: 100,
height: 100,
fit: BoxFit.cover,
),
),
if someone intends to create bordered circular image try this.
Using ClipOval widget is not perfect solution because if images are not square result will be elliptic.
CircleAvatar(radius: (52),
backgroundColor: Colors.white,
child: ClipRRect(
borderRadius:BorderRadius.circular(50),
child: Image.asset("assets/pictures/profile.png"),
)
)
ClipRRect widget prevents image to overflow CircleAvatar widget.
You will need to use NetworkImage, AssetImage, FileImage, MemoryImage or something similar. You can't directly use Image.network, Image.asset or similar due to how Flutter architects its image classes.
An example:
CircleAvatar(
radius: 100.0,
backgroundImage: NetworkImage(...),
)
backgroundImage in CircleAvatar expects to receive an ImageProvider as a parameter. However, Image.network and others don't directly extend the ImageProvider class, they merely extend the StatefulWidget class, even though they use NetworkImage inside. That is why you see in the other answers that ClipOval or ClipRRect is being used. These classes accept a Widget and so they're not as particular as CircleAvatar and similar classes are.
Instead of these workarounds, therefore, for CircleAvatar, you should use NetworkImage and similar classes and for widgets that expect just a Widget, you can use Image.network and similar.
Another reason not to use clips is that they can be more expensive than changing the border radii directly: https://flutter.dev/docs/perf/rendering/best-practices
simply use backgroundImage inside CircleAvatar
CircleAvatar(
backgroundImage: AssetImage("assets/images/dia.jpg",),
),
CircleAvatar(
radius: 26,
backgroundColor: Colors.white,
child: ClipOval(
child: _bytesImage == null
? new Text('No image value.')
: Image.memory(
_bytesImage,
width: 60,
height: 60,
fit: BoxFit.cover,
),
),
),
If anyone is trying to fit a circular image in app bar actions. Try below solution it should work.
Padding(
padding: const EdgeInsets.all(8.0),
child: AspectRatio(
aspectRatio: 1,
child: CircleAvatar(
backgroundImage: NetworkImage('https://picsum.photos/seed/picsum/200/500'),
),
),
)
AspectRatio first tries the largest width permitted by the layout constraints(here the appbar). If I remove the padding image radius will be of appbar size. So add padding to control the size of circular image.
this work for me
CircleAvatar(
child: ClipRRect(
borderRadius: new BorderRadius.circular(100.0),
child:Image.network("http://www.rd.com/wp-content/uploads/2017/09/01-shutterstock_476340928-Irina-Bg-1024x683.jpg"),
),),
Wrap your CircleAvatar widget under Stack widget.
return Stack(
children: [
CircleAvatar(
radius: 50.0,
backgroundImage: NetworkImage(
'https://i.pinimg.com/474x/0c/eb/c3/0cebc3e2a01fe5abcff9f68e9d2a06e4.jpg'),
),
],
);
Here is a round picture with a shadow:
child: AspectRatio(
aspectRatio: 1/1,
child: Container(
margin: EdgeInsets.all(
10.0
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100.0),
boxShadow:[
BoxShadow(
color: Color.fromARGB(60, 0, 0, 0),
blurRadius: 5.0,
offset: Offset(5.0, 5.0)
)
],
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(user.image)
)
)
)
)
I had the same problem
CircleAvatar(
radius: 30.0,
backgroundImage: NetworkImage(imageURL),
backgroundColor: Colors.transparent,
));
fixed my issue.
ClipOval(
child: Image.asset(
'assets/dummy.jpg',
fit: BoxFit.contain,
matchTextDirection: true,
height: 50,
))
Use combination of width/height, fit and wrap image in ClipOval like below:
CircleAvatar(
child: ClipOval(
child: Image.network(
_photo,
width: 120,
fit: BoxFit.fill
),
),
radius: 50,
),
If you want to show your image covering whole width of circle avatar then you can use it like this way. And if your image didnot load then it will show default person icon.
CircleAvatar(
child: ClipOval(
child: Center(
child: _image == null
? Icon(
Icons.person,
color: Colors.grey.shade700,
size: 100,
)
: Image.file(
_image,
fit: BoxFit.cover,
width: MediaQuery.of(context).size.width,
),
),
),
radius: 50,
backgroundColor: Colors.grey.shade300,
),
I had the same problem. Using clipoval in circle avatar will make it elliptical.
But this fixed this issue.
CircleAvatar(
radius:25.0,
backgroundImage: NetworkImage(
'${image_url}',
),
backgroundColor: Colors.blue,
),
CachedNetworkImage(
placeholder: (context, url) => Center(
child: CircularProgressIndicator(),
),
errorWidget: (context, url, error) =>
new Icon(Icons.error),
imageBuilder: (context, imageProvider) => Container(
width: 60.0,
height: 60.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: imageProvider,
fit: BoxFit.contain))),
fit: BoxFit.contain,
imageUrl:
"${Constants.MEDIA_LINK}${state.review.company.logo}"),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MyApp7()),
);
},
child: CircleAvatar(
radius: 50,
// backgroundColor: Colors.amber,
child: CircleAvatar(
backgroundColor: Colors.grey[50],
radius: 50,
// child: Image.asset("assets/images/nophotoMale.png")
backgroundImage:
AssetImage("assets/images/nophotoMale.png")),
),
),
],
),
Below worked in my case:
child: new CircleAvatar(
backgroundColor: Colors.white,
child: ClipRect(
child: Image.network(
'url-to-image',
fit: BoxFit.cover,
),
),
)
It took a few tries to figure this one out.. All these answers did not help me. In the end picture that I inserted into the circle avatar was stretched out to the boundaries of the container that was 2 instances above it. Maybe there are are people who, after going through the answers here, still have the problem that I had. I solved the constraint issue with a FittedBox
GestureDetector(
onTap: () => getImage(),
child: Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.orange,
),
//padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
child: Container(
width: 140,
height: 160,
child: FittedBox(
child: picture(),
)),
),
),
This is the code for the picture() that I use. I think that the container inside the picture() is not necessary anymore, try it yourself :)
Widget picture() {
if (_image == null) {
return CircleAvatar(
radius: 70,
child: Icon(
Icons.person,
size: 150,
color: Colors.grey[900],
));
} else {
return Container(
width: 140,
height: 140,
child: CircleAvatar(
radius: 70,
backgroundImage: FileImage(_image),
),
);
}
in this solution you can resize the image by container and clip image by clip Oval then add shadow to the image by card.
Container(
width: 100,
height: 100,
child: InkWell(
onTap: () {},
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.grey),
borderRadius: const BorderRadius.all(
Radius.circular(45.0),
),
),
child: Container(
child: ClipOval(
child: CachedNetworkImage(
imageUrl: '{image-url}',
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.fill,
),
),
),
placeholder: (context, url) => Container(
height: 5,
width: 5,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
),
errorWidget: (context, url, error) => Icon(Icons.error),
)),
),
),
));
This is work for me. I think that best way
CircleAvatar(
radius: 30,
backgroundColor: Colors.blueGrey.shade100,
child: Container(
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(shape:
BoxShape.circle),
child: const CachedNetworkImage(
url: "https://www.yourimage.com",
),
),
)
Came here as I also had the issue with CirclAvatar and AppBar, where the image would stretch in height. Instead of a radius, as I'm not able to provide it with the component I'm using, I just wrapped the image with a colum when used in appbar. This makes the image not stretch in height. This way I can always control size from the outside too
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 40, width: 40, child: ProfileBadge(),),
],
)
Use AvatarView lib https://pub.dev/packages/avatar_view which provides the functionality to show network/asset images in circular/rectangular form.
To use add below dependency
dependencies:
avatar_view: ^1.0.0+3
Example:
AvatarView(
radius: 60,
borderColor: Colors.yellow,
avatarType: AvatarType.CIRCLE,
backgroundColor: Colors.red,
imagePath:
"https://images.pexels.com/photos/415829/pexels-photo-415829.jpeg?cs=srgb&dl=pexels-pixabay-415829.jpg",
placeHolder: Container(
child: Icon(Icons.person, size: 50,),
),
errorWidget: Container(
child: Icon(Icons.error, size: 50,),
),
),
It also provide funtionality to add borders around widget, for more example visit above link
Output:
this worked for me
Transform.scale(
scale: 0.6,
child: ClipOval(
child: Image.network(
<IMAGE URL HERE>,
),
),
)
Related
Flutter: Transparent child with fill parent's background color
I am just trying to display the camera's preview and align the user to take a selfie. I have the following snippet of code and I would like to make the person's image transparent (not white) and fill the surrounding area with color. but the problem that I am facing, if I set the SVG with transparent color, it will display the color of the parent (container), I need to make the person's image totally transparent to see the camera's preview with filling the surrounding area with color. Widget build(BuildContext context) { return Scaffold( body: Center( child: Stack( children: [ Container( height: MediaQuery.of(context).size.height, child: Center( child: _cameraPreviewWidget(), ), ), Container( height: MediaQuery.of(context).size.height, color: Colors.grey[700].withOpacity(0.8), child: Align( alignment: Alignment.bottomCenter, child: SvgPicture.asset( 'assets/svg/selfie_person.svg', alignment: Alignment.bottomCenter, fit: BoxFit.cover, color: Colors.white, ), ), ), Container( height: MediaQuery.of(context).size.height, child: Padding( padding: EdgeInsets.only( top: MediaQuery.of(context).size.height * 0.05, bottom: MediaQuery.of(context).size.height * 0.15, ), child: Column( children: [ ListTile( leading: InkWell( onTap: () { Navigator.pop(context, null); }, child: FaIcon( FontAwesomeIcons.arrowLeft, color: Colors.white, ), ), title: Center( child: Text( "Take a selfie", style: Theme.of(context).textTheme.subtitle2, ), ), ), Padding( padding: EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.05, ), child: Text( "Take a quick selfie so we know it's you, this is never public", style: Theme.of(context).textTheme.subtitle2, overflow: TextOverflow.ellipsis, maxLines: 3, textAlign: TextAlign.center, ), ), Expanded( child: Align( alignment: Alignment.bottomCenter, child: _captureButton(), ), ), ], ), ), ), ], ), ), );
I don't understand your question well, but i think you should try Opacity class .. wrap your SVG with Opacity You can check it : https://api.flutter.dev/flutter/widgets/Opacity-class.html
Flutter crop 2 rotated images
I need to achieve this effect in Flutter: Example Any Ideas on how to do it? The Images should have their own separate widgets to be more flexible. Any help is really appreciated. Thank you. Solution for me: return Center( child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(10.0)), child: Container( color: Colors.blueGrey[900], child: SizedOverflowBox( size: Size(150, 150), child: Transform.rotate( angle: -math.pi / 4, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( kFlagPathUK, width: 220.0, ), SizedBox( height: 10.0, ), Image.asset( kFlagPathUSA, width: 220.0, ), ], ), ), ), ), ), ); Which looks like this: Solution
You can get the basic rotation an position with this code, and depending on you images you'll need to resize them and position them regarding the parent widget. return ClipRRect( child: Container( height: 300, width: 300, color: Colors.grey, child: Stack( children: [ Transform.translate( offset: Offset(-90, -100), child: Transform.rotate( angle: -math.pi / 4, child: Image.asset('flag1.png'), ), ), Transform.translate( offset: Offset(90, 100), child: Transform.rotate( angle: -math.pi / 4, child: Container( width: 500, child: Image.asset('flag2.png'), ), ), ), ], ), ), );
CircleAvatar flutter not fit the image inside the circle
please help, i need to put an image inside circleAvatar widget, but the image doesn't show perfectly. this issue, only shown on android devices return Center( child: CircleAvatar( radius: 100.0, backgroundImage: ExactAssetImage( 'assets/images/ic_Photo-L.png', ), ), );
Try using ClipOval with Container if CircleAvatar is not compulsory. return Center( child: ClipOval( child: Container( height: 200, width: 200, color: Colors.grey.shade200, child: Image.asset( 'assets/images/ic_Photo-L.png', width: 200.0, height: 200.0, fit: BoxFit.contain, ), ), ) );
Flutter how to handle image with fixed size inside box?
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, ))
Flutter CircleAvatar backgroundImage not filling up the circle
I am using a CircleAvatar with a backgroundImage property to load an image took from a camera but the image shown does not fill the entire circle avatar. It looks like a rectangular image in a circle. How do I make the image expand to cover the circle avatar? Thanks.
You can always create an image and manually clip it: ClipOval( child: Image.network( "url.jpg", fit: BoxFit.cover, width: 90.0, height: 90.0, ) ),
If you are using a local image from asset then you can use CircleAvatar as, CircleAvatar( backgroundImage: ExactAssetImage('assets/images/cook.jpeg'), // Optional as per your use case // minRadius: 30, // maxRadius: 70, ), If you are using a network image then you can use CircleAvatar as, CircleAvatar( radius: 30.0, backgroundImage: NetworkImage(imageURL), backgroundColor: Colors.transparent, ));
CircleAvatar( child: Image.network( items.logo, fit: BoxFit.fill, ), backgroundColor: Colors.transparent, radius: 30, )
This is my working example: Stack( fit: StackFit.expand, children: <Widget>[ CircleAvatar( radius: 30.0, backgroundImage: NetworkImage("https://via.placeholder.com/150/92c952"), backgroundColor: Colors.transparent, ), Padding( padding: const EdgeInsets.all(20.0), child: Image.asset( 'assets/photo-camera.png', width: 20.9, height: 19.9, ), ), ], ))