Shape is not working properly for circular property in flutter - user-interface

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,
),
),
)

Related

Flutter ClipRRect not working because of child Image height and width?

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,
),
),
],
),
),

Can't change height of image, while using expanded widget

Im trying to change the height of an image but when i change height only size of the container changes but the height of image stays the same.
Container(
color: Colors.white,
height: 250,
child: Row(
children: <Widget>[
Expanded(
flex: 3,
child: Container(
color: Colors.red,
// child: Padding(
// padding: const EdgeInsets.all(5.0),
child: Image(
height: 150,
// width: 100,
image: AssetImage("images/MiddleEarthWp.jpg"),
),
// ),
)),
Expanded(
flex: 7,
child: Container(
color: Colors.amber,
),
)
],
),
),
Before changing height of image and After changing a height
you're having this because your image is a child of the container and because you didnt specify the fit of the image , you can try this code :
Container(
// background to this Container.
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('images/background.png'),
fit: BoxFit.cover,
),
),

Circle Button with visible radius and Image as a child

Goal: Implementing perfect sized Circle Button with visible radius and Image as a child
Screenshot to demonstrate:
As you can see from the above picture, I tried many solutions that are mentioned here by the community here
Including:
CircleAvatar
CircleAvatar(
child: Image.asset('assets/images/gucci.jpg')
)
ClipRRect
ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Image.asset(
'assets/images/gucci.jpg',
height: 100.0,
width: 100.0,
)
)
Material widget with Ink.image as a child widget
Material(
elevation: 1.0,
shape: CircleBorder(),
clipBehavior: Clip.hardEdge,
color: Colors.transparent,
child: Ink.image(
image: AssetImage('assets/images/gucci.jpg'),
fit: BoxFit.cover,
width: 120.0,
height: 120.0,
child: InkWell(
onTap: () {},
)
)
)
Any ideas on how to implement this design?
There are a lot of options for you. One of them is 'FloatingActionButton'.
SizedBox(
width: 60,
height: 60,
child: FittedBox(
fit: BoxFit.contain,
child: FloatingActionButton(
onPressed: () {},
shape: CircleBorder(
side: BorderSide(
color: Colors.black,
width: 1,
),
),
backgroundColor: Colors.white,
child: Padding(
padding: EdgeInsets.all(5),
child: Image.asset('assets/images/gucci.jpg'),
),
),
),
)
I would prefer it over Container since all the button's attributes like onPressed or tap animation are already implemented in FloatingActionButton and you don't need to use GestureDetector or InkWell.
Also you can use CircleBorder in any other Buttons or Widgets which accept a ShapeBorder.
I am guessing you want some padding and a border around the button.
SizedBox(
width: 100,
height: 100,
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
border: Border.all(
width: 2,
color: Colors.black,
),
shape: BoxShape.circle,
),
child: Material(
elevation: 1.0,
shape: CircleBorder(),
clipBehavior: Clip.hardEdge,
color: Colors.transparent,
child: InkWell(
child: Ink.image(
image: AssetImage('assets/images/gucci.jpg'),
),
),
),
),
),
You can try using Container() and GestureDetector() for tap functionality, I guess this will do
Code
GestureDetector(
onTap: (){},
child: Container(
height: 120.0,
width: 120.0,
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 1.5),
borderRadius: BorderRadius.circular(80),
image: DecorationImage(
image: AssetImage('assets/images/gucci.jpg'),
fit: BoxFit.cover
)
)
)
)
You can change the thickness of the border by playing with the width in border: Border.all(color: Colors.black, width: 1.5) and for circular container, make changes in this line borderRadius: BorderRadius.circular(80),. This will help.
Wrap your Container with Inkwell or GestureDetector.
Here is sample code:
InkWell(
onTap: (){},
child: Container(
width: 65,
height: 65,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/gucci.jpg'),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.all(Radius.circular(50.5)),
border: new Border.all(
color: Colors.black,
width: 2.0,
),
),
),
)
GestureDetector(
onTap: (){},
child: Container(
width: 65,
height: 65,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/gucci.jpg'),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.all(Radius.circular(50.5)),
border: new Border.all(
color: Colors.black,
width: 2.0,
),
),
),
),

DecorationImage/Image as Child going outside of Container?

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

Flutter CachedNetworkImageProvider does not have a loading spinner

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.

Resources