I need to add padding (i.e. a space from screen edgess) for the first two widgets in a body column.
Scaffold(
body: Column(
children: [
// need to add padding for the next two widgets
Container(
child: Expanded(
child: Column(...),
),
),
Row(...),
// until here
Container(
child: Expanded(
child: Column(...
),
),
),
],
),
);
I tried to wrap them in a column again, but that gives the error:
RenderFlex children have non-zero flex but incoming height constraints
are unbounded.
I guess the problem is in wrapping the expanded column with new column. How to make that?
You need to wrap that newly created Column with another Expanded widget.
Scaffold(
child: Column(
children: [
Expanded(
child: Container(
child: Column(
children: [
Container(
child: Expanded(
child: Column(...),
),
),
Row(...),
],
),
),
),
...
margin inside Container does what you want
example
Container(
margin: EdgeInsets.only(
left: 10),
child:....
)
Bro, you need to wrap your first Column with Container first, or with SizedBox. The requirement is that you cannot set Column within unbounded Width or Height. Otherwise, it will give an error. So set it up first, and set the Expanded inside it.
Related
I'm trying to create a scrollable column that has a widget at the bottom of the screen if it does not fill it up. However, if it does it scrolls.
First I tried with a simple Column with MainAxisSize.max and Expand with an empty Container which worked well until the column overflowed.
[...]
Column(
mainAxisSize: MainAxisSize.max,
children: [
MyWidget(),
MyWidget(),
[...],
MyWidget(),
Expand(child: Container()),
ElevatedButton()
],
)
Then I searched and found the recommended solution for making a Column scrollable is the SingleChildScrollView. This made all of my widgets in the column disappear (which I am still unsure why) until I removed the Expand which although solved one problem, introduced another.
[...]
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
MyWidget(),
MyWidget(),
[...],
MyWidget(),
// Expand(child: Container()),
ElevatedButton()
],
)
)
So my question is, how can I make a Column both scrollable and if it does not need all the space to expand so that the last child is at the bottom of the screen?
IntrinsicHeight is too expensive to use but in this situation you have no choice. Try this:
LayoutBuilder(builder: (context, constraint) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraint.maxHeight),
child: IntrinsicHeight(
child: Column(
children: [
Container(
color: Colors.red,
height: 400,
width: double.infinity,
),
Expanded(
child: Container(
color: Colors.blue,
width: double.infinity,
),
),
],
),
),
),
);
})
in this example if you set height for blue container you will see the scrollview works, and if you use Expanded on it, it takes the available size.
I want to make the entire page in flutter scrollable, while the height in each element inside remains dynamic.
Now the two Expanded elements have fixed height and are vertically scrollable - I want to make them extend to their regular height and be able to scroll down to the next element.
body: Scaffold(
body: Column(
children: <Widget>[
Text(),
IntrinsicHeight( //This is fixed height and doesn't move
child: Text(),
),
new Divider(height: 0.1),
Text(),
Expanded( //This is now vertically scrollable in its own box
child: Text()
),
Expanded( //This is now vertically scrollable in its own box
child: Text()
),
],
),
),
I tired several versions of wrapping the first column in SingleChildScrollView but for some reason it doesn't work.
Try below code hope its helpful to you. Wrap your Column() inside IntrinsicHeight() widget,
Refere IntrinsicHeight here
Refere SingleChildScrollView here, this widget is used for Scrolling the Widget..
return Scaffold(
body: SingleChildScrollView(
child: IntrinsicHeight(
child: Column(
children: <Widget>[
Text(
'Try',
),
IntrinsicHeight(
child: Text(
'Done',
),
),
new Divider(height: 0.1),
Text(
'data',
),
Expanded(
child: Text(
'Okk',
),
),
Expanded(
child: Text(
'Yes',
),
),
],
),
),
),
);
Wrap your column with a SingleChildScrollView(), so select Column than wrap it with a widget witch is SingleChildScrollView()
Wrap your Column widget using IntrinsicHeight widget. Then wrap IntrinstHeight with SingleChildScrollView.
This work fine for me
body: SingleChildScrollView(
child: IntrinsicHeight(
child: Column(
children: <Widget>[
Text("tes"),
IntrinsicHeight( //This is fixed height and doesn't move
child: Text("tes"),
),
new Divider(height: 0.1),
Text("tes"),
Expanded( //This is now vertically scrollable in its own box
child: Text("tes")
),
Expanded( //This is now vertically scrollable in its own box
child: Text("tes")
),
],
),
),
),
Note: Put the code inside Scaffold body
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:
I'm so confused about how the clipping system in Flutter works.
So I will start with this example, Non of the shadow has been clipped.
Even the shadow was overflow from its self or its parent container.
Container(
child: Column(
children: [
Text("test"),
Container(
margin: paddingTheme.edgeInsets,
child: Row(
children: [
ShadowBox(),
ShadowBox(),
ShadowBox(),
],
),
),
],
),
)
Now if I add more ShadowBox() until it overflows, All the shadow will be clipped.
For example:
Container(
child: Column(
children: [
Text("test"),
Container(
margin: paddingTheme.edgeInsets,
child: Row(
children: [
ShadowBox(),
ShadowBox(),
ShadowBox(),
ShadowBox(), // ADD THIS
],
),
),
],
),
)
Now even I change Row to be SingleChildScrollView or List it's still clipped, But not overflow
Container(
child: Column(
children: [
Text("test"),
Container(
margin: paddingTheme.edgeInsets,
child: ListView.builder( // CHANGE FROM ROW TO LIST
scrollDirection: Axis.horizontal,
itemCount: 5,
itemBuilder: (c, i) => ShadowBox(),
),
),
],
),
)
So the question is how it's work, And how can I prevent these shadows to be clipped?
Or it's a design flaw of Flutter itself?
I had fire this in the Flutter's issue.
https://github.com/flutter/flutter/issues/67858
As I understand from now, The default ClipBehaviour of Container Row Column is different from ListView and internal Overflow.
So we have a workaround by adding clipBehaviour: Clip.none to the ListView.
Edit: To get the overlap shadows and no clipping, you can try:
In ShadowBox() widget,
Container(
height: 100,
width: 100,
margin: EdgeInsets.only(top: 20,bottom: 20), <-----
decoration:BoxDecoration(
color: Colors.white,
boxShadow: [BoxShadow(color: Colors.blue,blurRadius: 12)]
),
),
As for why it is clipped?
In Flutter engine, clipping the shadow is default behavior.
If you go deep in code you will find that shadow's width/height is not taken into account while rendering children in ListView or any widget. So you have to take care of it.
Why is it not clipping in Row/Column then?
In Rows and columns, no clipping is visible because it assumes the height of Row/Column as per the parent's max height/width. So it's height/width is at Max/Infinity.
So if you increase the width and height of the ListView()'s parent Container() widget, clipping will not happen as well.
I want to achieve the following look:
How can I make the FAB flex-ibly positioned in between these 2 widgets? (between top profile image and bottom profile info)
I've managed to make the 2 containers, but I haven't got a clue on how to position the FAB at the exact horizontal border of them.
My code (this is the entire widget tree, wrapped in a scaffold):
Row(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Expanded(
flex: 4,
child: Container(
decoration: BoxDecoration(color: Colors.grey.shade300),
),
),
Expanded(
flex: 6,
child: Container(),
),
],
),
),
],
),
You can use a Stack & Positioned widget together to position the FAB as per your requirement.
Stack(
children:[
// Add your existing row & it's child here,
Positioned(
child: FloatingActionButton(
onPressed:(){ },
child: Icon(Icons.camera_alt)
),
right: 5,
top: MediaQuery.of(context).size.height * .3,
)
],
),
And the output:
Note: You may need to tweak the top value of the positioned widget to place the FAB accurately in your case. If you know the exact height of that image widget, you can set top as height - 28.