Flutter: Sizing two Text children in a Row - flutter

I broke my brain trying to find a solution. I have a row constrained by screen width and unconstrained by height. Here is an example, constrained by Container for simplicity:
Container(
color: Colors.blue[100],
width: 300,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(width: 24, height: 24, color: Colors.red),
Flexible(
fit: FlexFit.tight,
child: Text('$name', overflow: TextOverflow.ellipsis)
),
Flexible(
fit: FlexFit.tight,
child: Text('$value', overflow: TextOverflow.ellipsis, maxLines: 10, softWrap: true, textAlign: TextAlign.right)
)
]
)
)
I need to size name and value according to this requirements:
Consider red square as icon with constant size
name is always 1 line with ellipsis if overflowed
value can be up to 10 lines with ellipsis if overflowed
In most cases value is pretty short, so name should take all available space
When value is long, it should take up to 10 lines in height and all available space in width leaving only 50 pixels for name. And 24 for icon of course. So name should have min width of 50px.
I have no idea how to achieve this. Please help.
P.S. I wrote a big Flutter project, solved huge amount of tricky tasks and Widget puzzles but this thing is something unbelievable.

Related

Starting a Column from the center of its parent

I am trying to implement a Column within a parent, but the first child of the Column should be centered vertically within the Column's parent, by using MainAxisAlignment.center the whole Column will be centered and if I have more than one child in the Column, the first child won't be in the center.
Here is what i have tried.
child: CircleAvatar(
radius: 146,
backgroundColor: Colors.black87,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('11:06',
style: TextStyle(
fontSize: 70,
)),
Icon(Icons.restart_alt),
],
),
),
Here is what i got.enter image description here
As you see the text is not in the center because the icon pushes it up a bit.
You can wrap your column in another column containing an Expanded widget followed by your column, also wrapped in an Expanded widget.
You can use some padding. I am not aware of a way to get the size of the parent and do like 50% of it like in CSS so you have to keep that in mind. However you can make calculations relative to the viewport height with MediaQuery.of(context).size.height.
Use Align inside Stack (not perfect, still needs adjustment).
CircleAvatar(
...
child: Stack(
alignment: Alignment.center,
children: const [
Text('11:06', style: TextStyle(fontSize: 70)),
Align(
alignment: Alignment(0, 0.4),
child: Icon(Icons.restart_alt),
),
],
),
)

Limit Child-Text to Column Size of child in Flutter

I want to make an image preview gallery like this. The height for the image is fixed to 150px using SizedBox. So I do not know the actual width of the image, depends on its aspect ratio.
Now, I want to have a description text, which I add as a column:
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 150,
child: Image.file(
File(artifacts[index].localartifactPath!),
fit: BoxFit.contain,
),
),
Text("Hello everyone this is my text",
maxLines: 2,
softWrap: true,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodySmall)
]),
But I do not want that the text is longer in width than the image, if the text is too long, it shall break into a second line and if still to long, it should use the ellipsis....
Is there any way to tell the Text widget not be longer (set constraints) in width than the Image widget?
Thanks!

My text is overflowing Pixels, how can I fix that and how do I increase the size of image

I have tried using Expanded and Flexible and none of it is working.I am not able to understand why.Also is this the best way to increase the size of image, because I want that my images looks size looks same across all devices.
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: size.width * 0.4,
height: size.width * 0.6,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/brushOne.jpg'),
fit: BoxFit.fill)),
),
Padding(
padding: const EdgeInsets.only(top: 40.0),
child: Text(
'Thank you for letting me do what I love, your support is contagious If I could put all 10,000 of you in a room and give you all a hug I WOULD. Your support makes my heart grow and glow. Thank you for helping me create a business and a family.I love you all 🌈',
),
),
],
)
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: MediaQuery.of(context).size.width * 0.4,
height: MediaQuery.of(context).size.width * 0.6,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images.jpg'),
fit: BoxFit.fill)),
),
Container(
child: Container(
padding: EdgeInsets.only(top: 40),
child: Text(
'Thank you for letting me do what I love, your support is contagious If I could put all 10,000 of you in a room and give you all a hug I WOULD. Your support makes my heart grow and glow. Thank you for helping me create a business and a family.I love you all 🌈',
),
width: MediaQuery.of(context).size.width * 0.6,
),
),
],
)
You set the first container to 40%.
width: MediaQuery.of(context).size.width * 0.4
If you set the width of the second container to 60%,
width: MediaQuery.of(context).size.width * 0.6
the problem will be solved. You can use sizedbox() to leave space between two containers if you want.
Wrap the padding widget fixed the problem:
The difference is the constraints passed to Text.
With Expanded, the constraints is fixed size:
Without Expanded, the constraints is infinity:
I suggest you to use ,
SizedBox(
width: 100,
child: Text(
"Thank you for letting me do what I love, your support is contagious If I could put all 10,000 of you in a room and give you all a hug I WOULD. Your support makes my heart grow and glow. Thank you for helping me create a business and a family.I love you all 🌈",
maxLines: 5,
overflow: TextOverflow.ellipsis,
),
),
Expanded should work as demoed in this quick mock-up here.
Like Engin has mentioned MediaQuery is your best bet for scaling contents to a device's screen, but if you're applying MediaQuery to both sections of the Row, you'll have to update both sizes each time you choose to resize one element. This is accruing unnecessary technical debt that will compound if you ever choose to add additional elements to the Row in the future. Expanded on the other hand will take up the remaining space without the need to manually calculate sizes each time you make a change to UI elements.

Flutter Layouts, expand Container in Column to match other widgets width

I am creating chat bubbles, I want the width to be defined by the message itself, but then I added a "header" (a Row) with the name of the sender and a decorative line (a Container).
I want this line to fill the available space but when I expand it it pushes the width of the bubble to its maximum regardles of the width of the message. In this sceenshots you can see that the recieved messages are too wide for its content.
This is a simplified version of the code, If I don't put the expanded the red Container is invisible (width 0), with the expanded takes the maximum space available but I want column to remain of the width that determines the message.
Thanks a lot.
return Container(
color: Colors.grey.shade200,
constraints:
BoxConstraints(maxWidth: (MediaQuery.of(context).size.width * 0.7)),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text("Juan"),
Expanded(
child: Container(
color: Colors.red,
height: 3,
),
)
],
),
Text("Text of the message"),
],
));
pskink nailed it. His answer in the comment:
you need: child: IntrinsicWidth(child: Column(... –
pskink
Hopes this also helps somebody else.

How do I give a container a preferred height that can later be changed?

This is my Container:
Container(
height: height - height * 0.4, //this is my preferred height.
width: width - width * 0.7,
decoration: decoration,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 25.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Image.asset(
'assets/opensource.png',
scale: 1.35,
),
text('Open Source Software', 20, Color(0xFF02bbe5)),
text('Contributor since December, 2020', 16,
Color(0xFF02bbe5)),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: text(
'test',
16,
Colors.blueGrey),
),
],
),
),
),
I need to make the app responsive, for that the Container needs to be elongated when the inner widgets don't fit inside the Container properly.
How do I give a preferred height to this Container but also allow it to resize freely in case of overflow?
Note: This Container is inside a Column itself with SingleChildScrollView as the parent. And I am building a web app.
Edit: I have used MediaQuery for getting width and height.
There are multiple ways to approach this problem. You can wrap you container inside an AspectRatio widget and an Expanded.
AspectRatio(
aspectRatio: someAspectRatioValue,
child: Expanded(
child Container(...)
)
)
This should expand the items container without loosing shape of the container.
You can also build your whole screen with a LayoutBuilder, though that would require a lot of reworking.
If you want to make your application responsive in Flutter then you should Sizer package( Here ). This package will make your app responsive for any screen size, it divides into percentages. For ex:
Container(
width: 20.w, //It will take a 20% of screen width
height:30.h //It will take a 30% of screen height
)