How to create a Column that defaults to a ListView as fallback if the content widgets are too large? - flutter

I have some widgets that I want to display on a screen.
If the screen is large enough, the widgets should be centered on it like this:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [...],
)
On small screens, I don't want the Column to overflow (black & yellow stripes) but instead, let the user scroll through them, as if they were in a ListView, like this:
ListView(
children: [...],
)
If I knew the dimensions of the widgets beforehand, I could change the layout to one of the above in a LayoutBuilder based on the incoming constraints.
However, I don't know how their dimensions, so is there any easy way to achieve this on the widget layer?

Use SingleChildScrollView with physics: ClampingScrollPhysics() to avoid unwanted scrolling, wrapped in Center widget.
e.g.
Center(
child: SingleChildScrollView(
physics: ClampingScrollPhysics(), // To prevent the content from being always scrollable even when overall height is smaller than the screen.
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [/*...*/],
)
)
)

You can wrap your column with a SingheChildScrollView and it should work for you.

Related

SingleChildScrollView inside SingleChildScrollView - can't scroll parent

I got a SingleChildScrollView looking like this:
Widget build(BuildContext context) {
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
scrollDirection: Axis.vertical,
child: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// ... some other widgets come here ...
CommunityListView(),
],
),
),
);
}
And the CommunityListView() inside of that is another SingleChildScrollView. My Problem is, once is scroll inside of the CommunityListView(), i can't get out of it and the user is stuck in this ScrollView.
Does someone know how I can fix that?
Thank you !
Please add physics to inner List as NeverScrollableScrollPhysics()
SingleChildScrollView is take height of their immediate child ..If you put SingleChildScrollView in their child then he can find the proper height so put height of first SingleChildScrollView's child then you can use it well

Restricting the size of widgets programmatically

I'd like to create the layout shown in the picture below. This shows up fine:
Column( Row, ListView()))
While this renders errors:
Column( Row, Row( ListView(), Column ))
As soon as I replace the inner ListView() with Row( ListView(), Column ), nothing shows up and I get varying error messages, based on various changes I did.
Most often, I see a 'viewport has unlimited horizontal size'.
I guess Listview to be the source of the problem. That said, I'm no aware how to fix it.
Furthermore, I did find various hints on SO, but none fixed the problem.
How do I fix the problem?
Update 1
While the right Column() may be fixed width, the ListView() should take all remaining space of the screen [= availableWidth - WidhtOf(Column())].
put the ListView inside a Container And give it height/width
code
Column(
children: [
Row(
children: [],
),
Row(
children: [
Container(
height: 100,
width: 100,
child: ListView(
children: [
Text(
"1 C/G")
],
)),
Column(
children: [],
)
],
)
],
),
Both Row and Column have a mainAxisSizeparameter where you can set it to MainAxisSize.min so they will take their children's size.
Now, about the ListView, there is a shrinkWrap parameter that makes it so its max size will be its children's size. Another idea might be using a Flexible widget around the ListView, it does almost the same as Expanded, but the difference is: Expanded forces the child to occupy the remaining space, while Flexible allows the children to have any given size smaller than that, and that's because of its fit parameter that by default is FlexFit.loose.

Flutter text widget: achieve horizontal vertical align; left-align horizontal

Good evening Stack Overflow.
Any advances on this Flutter code to achieve vertically-centered, but left-aligned text, in a simple full width container?
I found I had to fall back on making a secondary wrapper column around the text, and set BOTH mainAxisAlignment.center (for horizontal centering) and crossAxisalignment.start (to get left alignment).
I don;t want to set the Main column's axis alignments, as there will be other text widgets with different text alignments.
For the wrapper column I made it seems I can't just set mainAxisAlignment.center (for horizontal center) and then force textAlign.left in the Text widget itself. Surprised by that.
Anyway, the below code works, but surely there's a more efficient way?
body: SafeArea(
child: Column( //<-MAIN column for everything on the page
children: <widget> [
// A container for my text widget
Container(
height: 50;
width: double.infinity,
Child: Column( //<- had to make another wrapper column.
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
Children: [
Text('mytext')
]
),
) //container
] //children
)) //Main column and SafeArea
Cheers.
wrap your Text Widget in an Align Widget and set the alignment to centerLeft

Flutter: Need Explanation for Why Expanded() Fixes Exception Caused By Row() Widget As A Child Of A Constrained Column() Widget

I am having a problem with embedding a Row() widget as a child of parent Column() widget who was been constrained by a ConstrainedBox(maxHeight:150) widget.
With this scenario, I am getting a 'BoxConstraints forces an infinite height.' exception.
Here is the simplified code (I am only including the build() method for brevity):
#override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints(maxHeight: 150),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
color: Colors.yellow,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text("Hello"),
Text("There"),
],
),
),
],
),
);
}
I had read a previous post suggesting to use Expanded() to solve the exception so I wrapped the Container() widget above with Expanded() and that worked, but my question is WHY?
I was under the impression that Expanded() simply forces its associated child widget to occupy all of its parent's available space. But does it also get its child widget to recognize the constraints from its parent?
Another interesting aspect of this scenario is that if I wrap the Row() with Expanded() instead of Container(), it will not work and the exception will be thrown. For whatever reason, it has to be the Container().
All help greatly appreciated. I love Flutter, but I am still struggling with the nitty gritty of its layout algorithm.
/Joselito
This is because Rows and Columns will keep expanding based on their children,
for Row:- it will keep expanding horizontally and you'll usually see it overflows to the right of the screen.
For Column:- it will keep expanding vertically, and usually overflows the bottom.
By using Expanded, it will force Row and Column to expand infinitely, that is why there is an exception. It's different for container as it will follow it's parent's width and height.
https://flutter.dev/docs/development/ui/layout
I also had a lot of issues understanding constraints in flutter until I found this article. After a while I saw that the flutter team added the article in their documentation. Check it out, it's very good.

Flutter: How to add a column widget inside a bottom navigation bar

I've tried the following and got the out, but the body went blank.
Is there any way to add a coloumn or a listview inside a bottom navigation bar
Column(
mainAxisAlignment:MainAxisAlignment.end,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
//button1
),
Expanded(
//button2
),
Expanded(
//button3)
),
Row(
children: <Widget>[
Expanded(
//button4
),
Expanded(
//button5)
],
)
],
),
Apart from the issue posed by Expanded widget (as pointed out in the answer by alexandreohara),
Column's mainAxisSize attribute is set to MainAxisSize.max by default. That means the column will try to occupy all the space available (the entire screen height).
Setting Column's mainAxisSize to MainAxisSize.min will wrap the Column widget to occupy the least possible space(vertically) and not span the entire screen.
Following is the way it can be done:
Column(
mainAxisSize: MainAxisSize.min,
children: [...]
);
There's no problem using a Column in a BottomNavigationBar. I think that your problem is wrapping everything in Expanded. It doesn't know the width of the widgets inside, and because of that, it will return blank.
Try to remove those Expanded widgets and try this:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween
children: [FlatButton(...), FlatButton(...)],
)