Limit max width of Container in Flutter - user-interface

Widget build(context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 300,
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: color ?? Colors.blue,
borderRadius: BorderRadius.circular(10)
),
child: msg
)
],
);
}
This is build method of my widget and It renders this UI depending on what I pass as msg paramter
Loading text
Some very long text
Now the issue I am facing is that I am not able to wrap the text inside this container/blue box without setting it's width but If I set width of container/blue box then it will always stay that wide no matter how short the text is.
Now is there a way to set maxWidth (like let's say 500) of container/blue box? So that the blue box will become as wide as required for small text like "Loading" and for long text it will expand till it reaches width of 500 units and then will wrap the text ?
Required output for long text:
For small text like loading I dont want any change in UI but for long text I want it to look like this.

You can add a constraint to the Container Widget with the preferred maxWidth like this:
Widget build(context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
constraints: BoxConstraints(minWidth: 100, maxWidth: 200),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: color ?? Colors.blue,
borderRadius: BorderRadius.circular(10)
),
child: msg
)
],
);
}

Use ConstrainedBox with BoxConstraints maxWidth, wrapped in a Flexible() widget. The Flexible widget allows for the box to resize for smaller screens as well.
Flexible(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 150),
child: Container(
color : Colors.blue,
child: Text('Your Text here'),
),
),
),

This required to be inside Row or Column Widget
1. Row
Row(
children: [
Container(
constraints: BoxConstraints(maxWidth: 300),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0)),
child: Text("Long Text....")
),
],
);
2. Column
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
constraints: BoxConstraints(maxWidth: 300),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0)),
child: Text("Long Text....")
),
],
);
Here in both examples, it's working because Column and Row allow it's children to expand to it's given constraint/size.
Note: If a child wants a different size from its parent and the parent doesn’t have enough information to align it, then the child’s size might be ignored.

Here's a simple method I use for long texts:
ConstrainedBox(
constraints: BoxConstraints(maxWidth: 200),
child: Container(
child: Text(
'Long string of text',
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
)
Note the maxLines attribute which might be helpful should you wish to show just a single line of text.

Use Constraints property in Container widget.
use maxWidth & minWidth value to achieve the requirement.
Container(
constraints: BoxConstraints(minWidth: 150, maxWidth: 300),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5)),
child: Text("")
)

This is how i fixed it
Center(
child: Container(
child: this.child,
width: 300,
height: double.infinity,
),
)

For me at least putting the Constrained box in IntrinsicWidth has solved issue.
IntrinsicWidth(
child: Container(
constraints: BoxConstraints(maxWidth: 200),
child: Row(
children: [
],
),
),
);

Maybe use a Flexible around the text and then wrap the Flexible in a fixed size containter? Just an idea.

I know it's late, but someone may get help in the future.
I used the auto_size_text plugin to get it done:
AutoSizeText(
'A really long String',
style: TextStyle(fontSize: 30),
minFontSize: 18,
maxLines: 4,
overflow: TextOverflow.ellipsis,
)

In my case my solution was this:
Wrapped in Row and add Spacer (in comment bubble widget I didn't define either width any max-width. it grows depends on the text.
to limit width added padding to comment bubble.
return Row(
children: [
CommentBubble(
chatText: snapshot.get('text'),
sentAt: snapshot.get('sentAt'),
sendBy: snapshot.get('sendBy'),
),
Spacer(),
],
);

Related

Fix multiple image size with same dimension in flutter

my code is inside a ListView Widget. i am having a problem with my images, since each one of them have a dimensions which is different than the other ones. i want them to appear all with the same dimension, but some of them is being bigger than the others.
note : i have used Width and Height and it didn't help
i want both of them to be with the same dimension but the second one is bigger !
i have even tried the BoxFit method as well and didn't help.
here is my code sample:
ListView(
children: List.generate(
sandwichFood.length,
(index) => Padding(
padding: EdgeInsets.all(10),
child: Container(
padding: EdgeInsets.only(left: 10),
decoration: _foodDecor(),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
children: [
Text(
sandwichFood[index],
style: TextStyle(fontSize: 25),
textAlign: TextAlign.left,
),
Text(
'Price : ${sandwichPrice[index]}',
style: TextStyle(fontSize: 20),
),
],
),
Image(
image: AssetImage(sandwichImage[index]),
height: 200,
width: 200,
),
],
),
),
),
),
);
Image class has parameter fit. Try to use it:
Image(
image: AssetImage(sandwichImage[index]),
fit: BoxFit.cover,
height: 200,
width: 200,
)

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

Child container of AlertDialog not covering width

I want to show a popup on a button tap. When I am trying to show AlertDialog with my custom design child Container of this AlertDialog not covering whole space. It has some padding from corners.
I have implemented in this way:
AlertDialog(
shape: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.0)
),
content: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
color: Colors.redAccent,
width: screenSize.width,
height: screenSize.height*.90,
child: Text('test'),
)
],
),
),
)
For more info I am adding screenshot.
I found the solution for this. I resolve this issue by adding following tag in AlertDialog:
contentPadding: EdgeInsets.all(0.0),

Flutter Network Image does not fit in Circular Avatar

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

How do I center text vertically and horizontally in Flutter?

I'd like to know how to center the contents of a Text widget vertically and horizontally in Flutter.
I only know how to center the widget itself using Center(child: Text("test")) but not the content itself. By default, it's aligned to the left. In Android, I believe the property of a TextView that achieves this is called gravity.
Example of what I want:
Text alignment center property setting only horizontal alignment.
I used below code to set text vertically and horizontally center.
Code:
child: Center(
child: Text(
"Hello World",
textAlign: TextAlign.center,
),
),
You can use TextAlign property of Text constructor.
Text("text", textAlign: TextAlign.center,)
I think a more flexible option would be to wrap the Text() with Align() like so:
Align(
alignment: Alignment.center, // Align however you like (i.e .centerRight, centerLeft)
child: Text("My Text"),
),
Using Center() seems to ignore TextAlign entirely on the Text widget. It will not align TextAlign.left or TextAlign.right if you try, it will remain in the center.
child: Align(
alignment: Alignment.center,
child: Text(
'Text here',
textAlign: TextAlign.center,
),
),
This produced the best result for me.
THE TEXT TITLE MUST BE ALWAYS ON TOP.
wrong way:
child: Center(
child: Text(
textAlign: TextAlign.center,
"Hello World",
),
),
right way:
child: Center(
child: Text(
"Hello World",
textAlign: TextAlign.center,
),
),
U need to use textAlign property on the Text widget. It produced the best results for me
Text(
'Hi there',
textAlign: TextAlign.center,
)
If you are a intellij IDE user, you can use shortcut key Alt+Enter and then choose Wrap with Center and then add textAlign: TextAlign.center
Put the Text in a Center:
Container(
height: 45,
color: Colors.black,
child: Center(
child: Text(
'test',
style: TextStyle(color: Colors.white),
),
),
);
Text element inside Center of SizedBox work much better way, below Sample code
Widget build(BuildContext context) {
return RawMaterialButton(
fillColor: Colors.green,
splashColor: Colors.greenAccent,
shape: new CircleBorder(),
child: Padding(
padding: EdgeInsets.all(10.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
width: 100.0,
height: 100.0,
child: Center(
child: Text(
widget.buttonText,
maxLines: 1,
style: TextStyle(color: Colors.white)
),
)
)]
),
),
onPressed: widget.onPressed
);
}
Enjoy coding 👨‍💻
Overview: I used the Flex widget to center text on my page using the MainAxisAlignment.center along the horizontal axis. I use the container padding to create a margin space around my text.
Flex(
direction: Axis.horizontal,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(20),
child:
Text("No Records found", style: NoRecordFoundStyle))
])
you have to set your Text widget property to set textAlign.center.
center(
child : Text(
'Hello',
textAlign: TextAlign.center))
Wrap your Text widget inside the Align widget and add Alignment.center.
Align(
alignment: Alignment.center,
child: Text(
'Some Text',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
)
maybe u want to provide the same width and height for 2 container
Container(
width: size.width * 0.30, height: size.height * 0.4,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6)
),
child: Center(
child: Text(categoryName, textAlign: TextAlign.center, style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 17,
color: Colors.white,
),),
),

Resources