Flutter - Column that takes the height of its children - flutter

Is it possible to arrange children vertically in a way that the parent will take the size of its children?
More specifically, here's what I'm trying to do:
Have an icon and a text aligned vertically with a small space between them, centered within a rectangle with a fixed height.
I'd like the size of the vertical container of the text and icon to be according to its children.
Something like FlatButton.icon, only vertical instead of horizontal.
For that inner vertical container, all I found were Column and ListView, both of which take all the height they can get within their parent, rather than take the height of their children.

That sample code should do the job :
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: Container(
child: Center(
child: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.star,
size: 50.0,
),
SizedBox(
height: 30,
),
Text(
'Some text',
textAlign: TextAlign.center,
)
],
),
color: Colors.blue,
width: 120)),
width: 300,
height: 300,
color: Colors.green),
),
],
)
Thanks to the mainAxisSize: MainAxisSize.min,

Related

Flutter column with elements aligning to different sides without stretching the width of the column

I'd like to have a column take the width of the content, and have some elements align to right and some to the left.
Is this possible?
If I use Align widget on the children the whole column stretches in width. Is there another way?
Thank you
Edit: Example
Center(
child: Container(
color: Colors.yellow,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.red,
width: 50,
height: 50,
),
Text('Here goes some text with variable length'),
Container(
color: Colors.blue,
width: 50,
height: 50,
),
],
),
),
);
I want the column above with the red square to the left and the blue to the right (and the column not stretching to the available width).
Try this-
Center(
child: Container(
color: Colors.yellow,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
color: Colors.red,
width: 50,
height: 50,
),
],
),
SizedBox(width: 100),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
color: Colors.blue,
width: 50,
height: 50,
),
],
),
],
),
),
)
You can simply try to put the contents of the column in a row, so you would have elements inside containers for their width and height as you like.
Column -> Row -> aligned containers.

Expand Container to fill remaining space in Column

I have a problem with building a specific layout in flutter.
What I need is:
Scrollable screen, with two columns, where the first col is of certian (but dynamic) height. And the second col has part of certain (but dynamic) height and the rest of the col I want to fill remaining space.
The code structure.
Row(
children: [
Expanded(
child: Column(children:[
someDynamicHeightWidgetsHere()])),
Expanded(child: Column(children: [
someWidgetsHere(),
here fill remainind space to match the first column]))
]
)
Use IntrinsicHeight, This widget only expands to its child height.
This class is useful, for example, when unlimited height is available and
you would like a child that would otherwise attempt to expand infinitely to
instead size itself to a more reasonable height.
Example:
IntrinsicHeight(
child: Row(
children: [
Expanded(
child: Column(
children: [
Container(
height: 800,
color: Colors.blue,
),
],
),
),
Expanded(
child: Column(
children: [
Container(
height: 400,
color: Colors.red,
),
Expanded(
child: Container(
color: Colors.yellow,
),
),
],
),
),
],
),
Output:

Vertically center content inside SingleChildScrollView with min height of screen height

I am trying to create a web layout that that consists of a scrollable column that has a min height of the screen height but can expand past the screen height if the content is too large. I have been able to create the scrolling container but I cannot vertically center the main content while still making the entire sections scrollable. The only working version I can get wont vertically center the content, I have to added a SizedBox above it to create padding to make it look centered but then its not responsive on different heights.
The parent of the content looks like this:
Container(
width: MediaQuery.of(context).size.width / 2,
height: double.infinity,
padding: const EdgeInsets.fromLTRB(100, 30, 100, 0),
child: SingleChildScrollView(
child: Column(
children: [
LoginLayout(),
SizedBox(height: 30),
],
),
),
),
Then to simplify the content column, its basically this:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 30),
child: Image.asset(
'assets/images/2.0x/logo-full.png',
width: 125,
fit: BoxFit.contain,
),
),
// This column needs to be vertically centered if fits in the screen height
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text('Welcome Back!', style: _textTheme.headline2),
SizedBox(height: 10),
Text('Sign in to continue', style: _textTheme.bodyText2),
SizedBox(height: 60),
EmailInput(label: 'EMAIL'),
SizedBox(height: 30),
PasswordInput(label: 'PASSWORD'),
SizedBox(height: 60),
Button(
label: 'Login',
icon: Icons.link,
theme: ButtonColor.PRIMARY,
onPressed: () {},
),
],
),
],
);
I was able to apply an Expanded widget around the centered column which did work but then I lost the ability to scroll if the content was larger that the screen height.
Here is an example for reference as well
Not sure how to do that in SingleChildScrollView though,
try using ListView with shrinkWrap: true
Container(
width: MediaQuery.of(context).size.width / 2,
height: double.infinity,
padding: const EdgeInsets.fromLTRB(100, 30, 100, 0),
child: Center(
child: ListView(
shrinkWrap: true,
children: [
LoginLayout(),
],
)
),
)

Word-wrapping do not working with long text

Here is my widget:
return Card(
child: Container(
height: 150,
child: Row(
children: <Widget>[
Placeholder(
fallbackHeight: 100,
fallbackWidth: 100,
),
Container(
width: _deviceHeight,
color: Colors.red,
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Flexible(
child: Text(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
overflow: TextOverflow.ellipsis,
maxLines: 4,
)),
// Expanded(flex: 8, child: Text("bbb")),
Flexible(child: Text("bbb")),
// Flexible(child: Text("aaa")),
],
),
)
],
),
));
I expected that text will be placed on new line, but I am getting overflow:
Wrap your inner Container with an Expanded to provide it with the available parent constraints, otherwise the Container has infinite height and will result in an overflow (because you are on landscape).
Expanded(
child: Container(
width: _deviceHeight,
color: Colors.red,
child: Column(
...
You could wrap the second element of the Row with Flexible, like this:
Row(
children: <Widget>[
Placeholder(..),
Flexible(
child: Container(
color: Colors.red,
child: Column(...
Inside the Row you need Placeholder to keep its width and Container width to be flexible.
Edit: And you should remove the width of the Container, since it would be flexible and it should take as much as possible to fit the screen.

Flutter - Expanded doesn't take all available space when a sibling is Flexible

Image of the problem, shown as colored rectangles
I want the first child of Column to be Flexible and the second to take up the entire remaining space. Apparently, this does not work.
I'm now aware that this is the expected behavior. I would appreciate a workaround.
I've tried using FittedBox on the first child instead of Flexible, but it didn't work as the content of the first child has unbounded width.
SizedBox(
height: 300,
width: 50,
child: Container(
color: Colors.black,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: Container(
height: 100,
color: Colors.red,
),
),
Expanded(
child: Container(
color: Colors.blue,
),
),
],
),
),
);
I want to make the first child (i.e. A TextField) Flexible so that if the height gets too small, there are no ugly yellow-black overflow bars.
Update:
Below image shows what I really want to do, but it has the overflow issue because the first child isn't flexible.
shows what happens when I do use Flexible.
I'm using AnimatedContainer to change the height. I prefer not to use SizeTransition if possible.
Just replace your code with the next one (flexes ratio can be adjusted to the right one):
SizedBox(
height: 300,
width: 50,
child: Container(
color: Colors.black,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
flex:1
child: Container(
height: 100,
color: Colors.red,
),
),
Flexible(
flex:10
child: Container(
color: Colors.blue,
),
),
],
),
),
);