Completely center Widget in Flutter - flutter

I started to develop in Flutter recently and I am having difficulties in centralizing a Widget completely in the available space of View.
This is how it looks:
And here's what I want to achieve:
And here's my code:
LayoutBuilder(builder:
(BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Column(children: [
NavHeader("Deposit"),
BalanceHeader(widget.usd),
]),
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"How much do you want deposit?",
style:(
...
),
),
Container(
alignment: Alignment.center,
width: width * 0.4,
margin: EdgeInsets.only(top: 10),
child: Row(
...
),
),
],
),
],
),
),
);
}),
bottomNavigationBar: BottomAppBar(
...
),
),
);
}

By using MainAxisSize.min The height of the Column will be according to the combined height of its children and incoming height from the parent will be ignored. That means your column height has shrinked to its children.
There is you can use MainAxisSize.max instead of MainAxisSize.min to max height of column. And also you have to use mainAxisAlignment: MainAxisAlignment.center for aligning childrens to center of column.
Your Second Column
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"How much do you want deposit?",
style:(
...
),
),
Container(
alignment: Alignment.center,
width: width * 0.4,
margin: EdgeInsets.only(top: 10),
child: Row(
...
),
),
],
),
Edited Column
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center
children: [
Text(
"How much do you want deposit?",
style:(
...
),
),
Container(
alignment: Alignment.center,
width: width * 0.4,
margin: EdgeInsets.only(top: 10),
child: Row(
...
),
),
],
),

Well, there is a widget for that!
As for most things in flutter just Wrap the Widgets you want centered inside a Center widget and you should achieve what you want.

Column(
mainAxisAlignment: MainAxisAlignment.center,
children ... Your code
)

You could also wrap your widget with the Column widget and it will work only for the X coordinates.
(It has already been stated but poorly)

Related

Flutter BoxConstraints maxWidth in CustomScrollView not working

I am using a CustomScrollView and tried to limit its children's size by using BoxConstraints but they are simply ignored. My text expands to the width of the screen and I don't understand why.
This is my code:
SliverToBoxAdapter(
child: ConstrainedBox(
constraints: maxWidthConstraint,
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.project.description,
),
],
),
),
),
),
What am I missing here? Let me know if you need any more info!
The parent forces it to be the full width so you can wrap it with UnconstrainedBox or Align or Center widget to get rid of that behavior.
SliverToBoxAdapter(
child: UnconstrainedBox( // this should allow it to have its own constraints
child: ConstrainedBox(
constraints: maxWidthConstraint,
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.project.description,
),
],
),
),
),
),
)

Having trouble centering a row widget

I have a Row widget on the bottom of the page that I can't center. I've tried all the mainAxisAlignment's and crossAxisAlignment's there are, as well as wrapping it in an Align widget and setting alignment to alignment.center and it's still on the left edge of the page. I've tried everything and am really stuck. Any help would be appreciated.
The Page (Updated)
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.lightBlue,
centerTitle: true,
elevation: 5,
title: Text("Pathomatic")),
body: Container(
decoration: new BoxDecoration(color: Colors.black),
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 2,
child: new Stack(
children: <Widget>[
new Container(
alignment: Alignment.center,
child: _cameraPreviewWidget(context),
),
new Align(
alignment: Alignment.center,
child: GestureDetector(
child: Stack(children: <Widget>[
Positioned(
top: yPosition,
left: xPosition,
child: Container(
// padding: EdgeInsets.only(top: 200.0, left: 20.0),
height: MediaQuery.of(context).size.height / 3,
width: MediaQuery.of(context).size.width / 3,
child:
Image.asset('assets/images/crosshair.png'),
),
),
]),
onPanUpdate: (tapInfo) {
setState(() {
xPosition += tapInfo.delta.dx;
yPosition += tapInfo.delta.dy;
});
}),
),
],
),
),
SizedBox(height: 5),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
_cameraTogglesRowWidget(),
_mlTextWidget(),
],
),
_captureControlRowWidget(context),
//SizedBox(width: 50),
],
),
SizedBox(height: 5),
],
),
),
),
);
}
This is usually because the widget you are trying to center is actually stretching its container. Since it's the size of the screen, it's contents stick to the left. You should use the Flutter Inspector with select widget mode to actually see how large your row is. Then everything will make much more sense.
In your code, your Row is stretching. Try
Row(mainAxisSize: MainAxisSize.min
This should make it not grow. Alternatively, you can keep the row large but make it center its children:
Row(mainAxisAlignment: MainAxisAlignment.Center
Of course, with this approach its children will get close to each other in the center. You can use a SizedBox between them, or use some other way of spacing them apart.

Column's MainAxisAlignment has no effect when nested in Column->Row

I'm trying to get working the MainAxisAlignment property on the Column, but it's not working quite expected. Here is my code.
Scaffold(
appBar: AppBar(
title: Text('Account'),
),
body: Container(
child: Column(
children: <Widget>[
Card(
margin: EdgeInsets.only(left: 0.0, right: 0.0, top: 0.0, bottom: 20.0),
child: InkWell(
onTap: () {},
child: Padding(
padding: EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Image.network(
'https://cdn.mydomain.com/Color/PNG/512/profile-512.png',
height: 72.0,
),
SizedBox(width: 8.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround, // <<<=== this line
children: <Widget>[
Text('User\'s display name'),
Text('user#company.com'),
],
)
],
),
),
),
)
],
),
),
)
My hierarchy is Container->Column->Card->InkWell->Row->Column. The innermost Column widget has a problem. I figured out that If I remove the first Column widget then the MainAxisAlignment just works fine.
But I can't do that as I want to build a Column layout with various Cards inside it, as you can see in the code.
Could somebody please let me know what is this weird behaviour and a solution around this?
Regards.
Try to wrap this column in a Container or SizedBox and set a double.infinity height for it.
The problem that's happening it's because a Column or any component which you don't set a height or width, will automatically adjust to the widgets inside of it.
Container(
height: MediaQuery.of(context).size.height, //Add here
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text('User\'s display name'),
Text('user#company.com'),
],
),
),
OBS: I personally like to use MediaQuery for this. eg: MediaQuery.of(context).size.height to get the full height of the device, then, you can manipulate it, dividing by 2, 3, subtracting...

Flutter put row into row

I need to create the following:
I could do it with code:
Row(
children: <Widget>[
Container(
width: 30
),
Column(
children: <Widget>[
Text("label"),
Container(
width: screenSize.width - 30, // <- this is problem
child: Row(
children: <Widget>[
Expanded( child: TextField() ),
Expanded( child: TextField() ),
],
),
),
],
),
],
);
Is it possible to do it in a different way, namely the line width: screenSize.width - 30?
You can use crossAxisAlignment inside Column widget and make it Stretch to get all remaining width in screen
Row(
children: <Widget>[
Container(
width: 30
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // <- Add this
children: <Widget>[
Text("label"),
Container(
child: Row(
children: <Widget>[
Expanded( child: TextField() ),
Expanded( child: TextField() ),
],
),
),
],
),],);
[Please read official flutter documentation of Column widget]
Column Widget
CrossAxisAlignment
Solution
Row(
children: <Widget>[
Container(
color: Colors.red,
width: 50,
),
Expanded(
child: Column(
children: <Widget>[
Text("label"),
Expanded(
child: Row(
children: <Widget>[
Expanded(
child: TextField()
),
Expanded(
child: TextField()
),
],
),
),
],
),
),
],
);
Explanation
It is about where you place Expanded instances.
You have a row, which can fill its parent if it included an Expanded child. So we defined the size of one of its children (Container), and the other is simply Expanded. The same goes for the Column child ..
Maybe starting with a simpler example makes it easier to understand. Please refer to this useful answer.
Output
P.S. Welcome to StackOverFlow, Dmitry!

Flutter: Trying to bottom-center an item in a Column, but it keeps left-aligning

I'm trying to bottom-center a widget at the bottom of a Column, but it keeps aligning to the left.
return new Column(
new Stack(
new Positioned(
bottom: 0.0,
new Center(
new Container(),
),
),
),
);
The existence of the Positioned forces the Container to the left, instead of centering. Removing the Positioned, however, puts the Container in the middle-center.
Align is the way to go if you have only one child.
If you have more, consider doing something like this:
return new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
// Your elements here
],
);
The easiest and the correct way to do it - use Spacer()
Example:
Column(
children: [
SomeWidgetOnTheTop(),
Spacer(),
SomeCenterredBottomWidget(),
],
);
Expanded(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 10.0),
child: //Your widget here,
),
),
),
I have used this approach,
What i want is, A layout always in bottom but whenever Keyboard pops-up that layout also comes over it
body: Container(
color: Colors.amber,
height: double.maxFinite,
child: new Stack(
//alignment:new Alignment(x, y)
children: <Widget>[
new Positioned(
child: myWidget(context, data.iconName, Colors.red),
),
new Positioned(
child: new Align(
alignment: FractionalOffset.bottomCenter,
child: myWidget(context, data.iconName, Colors.green)
),
)
],
),
),
1) You can use an Align widget, with FractionalOffset.bottomCenter.
2) You can also set left: 0.0 and right: 0.0 in the Positioned.
Just expanding the answers:
Spacer is an option no one mentioned yet; it is used in case you prefer not to use Positioned / Align.
Align works if you want to specify the alignment of a child inside a parent. Use it anywhere but directly inside Stack
Positioned is similar to Align, but works only under Stack directly.
Design everything using Expanded() is one of the easiest way to do this
Column(
children: [
Expanded(
child: Placeholder(),
flex: 1,
),
Expanded(
child: Placeholder(),
flex: 10,
),
Expanded(
flex: 2,
child: Placeholder(),
)
],
),
If you wish to leave content as it, can wrap it with scrollable.
Useful if you have inputs in the children:
return Stack(
children: <Widget>[
Positioned(
child: SingleChildScrollView(
child: Column(
children: children
..add(Container(
height: 56, // button heigh, so could scroll underlapping area
)))),
),
Positioned(
child: Align(
alignment: Alignment.bottomCenter,
child: button,
),
)
],
);
Widget _bottom() {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Container(
color: Colors.amberAccent,
width: double.infinity,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<int>.generate(50, (index) => index + 1)
.map((item) {
return Text(
item.toString(),
style: TextStyle(fontSize: 20),
);
}).toList(),
),
),
),
),
Container(
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'BoTToM',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 33),
),
],
),
),
],
);
}
Wrap your Container in SingleChildScrollView() widget. Then it will not come above when keyboard pops up.
In addition of Stack:
to avoid floating container on keyboard, use this
return Scaffold(
appBar: getAppBar(title),
resizeToAvoidBottomInset: false,
body: