how to align children of Row? I tried crossAxisAlignment: CrossAxisAlignment.end, but I don't want CrossAxisAlignment my all children of Row widgets. and also I tried with Align widget for the specified widget(+1 and circle)
Container(
padding: EdgeInsets.only(top: 5.0),
child: Column(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Align(
alignment: Alignment.topLeft,
child: Text('Colombo - New York'),
),
Column(
children: <Widget>[
Row(
children: [
Column(
children: <Widget>[Text('Upper Left')],
),
SizedBox(height: 200, child: const Card(child: Text('Column 1'))),
SizedBox(height: 200, child: const Card(child: Text('Column 2'))),
SizedBox(height: 200, child: const Card(child: Text('Column 3'))),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[Text('Bottom Right')],
)
]),
],
)
],
),
)
the output is all widgets is center
the way I want,
I am not sure that I totally understand the question, but it seemed in the comments of your code that you wanted to align something top left and something else bottom right with 3 columns vertically aligned with each other in the center.
If that is the case, you should probably study or do some tutorials on the layout system for Flutter.
Here is what it seemed you were trying to do based on reading your code comments:
This was generated with the following code:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Layout Example'),
backgroundColor: Colors.blueGrey[900],
),
backgroundColor: Colors.blueGrey[50],
body:
Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
Column(
children: <Widget>[Text('Upper Left')],
),
SizedBox(height: 200, child: const Card(child: Text('Column 1'))),
SizedBox(height: 200, child: const Card(child: Text('Column 2'))),
SizedBox(height: 200, child: const Card(child: Text('Column 3'))),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[Text('Bottom Right')],
)
]),
),
),
);
Whether that totally reflects what you are looking for, or not, perhaps you will find it to be a good starting point where you can get some ideas for what you want to do.
Edit:
In response to your question above, you did not include the Row widget from the example I gave. Note, there is a row that has 5 widgets that will all space evenly on the main/horizontal axis. The first widget is a column and by default the Text widget in it will go to the top of that column. The next 3 columns are widgets (I just chose Size Box as a way to force in some height). Those 3 widgets are centered vertically in the row. The last thing in the row is a Column widget that has a main axis alignment of end forcing the widget in that column (Text/BottomRight) to go at the bottom of that column.
I took your code which was missing the Row widget container and added it back in and the output looked like the screen shot I sent before. Here is your code after I modified it:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Layout Example'),
backgroundColor: Colors.blueGrey[900],
),
backgroundColor: Colors.blueGrey[50],
body: Container(
// padding: EdgeInsets.only(top: 5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: <Widget>[Text('Upper Left')],
),
SizedBox(
height: 200,
child: const Card(child: Text('Column 1'))),
SizedBox(
height: 200,
child: const Card(child: Text('Column 2'))),
SizedBox(
height: 200,
child: const Card(child: Text('Column 3'))),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[Text('Bottom Right')],
)
]),
)),
),
);
Related
There is a box in which I need to animate a child consisting of a Row in which there are two Text. (In short - running line). Both texts in the result must be on the same line.
The child I want to animate is wider than the parent anyway and when animating, an overflow error pops up.
Overflow error
How can this be avoided?
This is code:
final Widget content = SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('TEXT 1'),
Text('TEXT 2')
],
),
);
#override
Widget build(BuildContext context) {
return
Container(
alignment: Alignment.center,
width: widget.parentWidth,
height: UI_SIZE,
child: ClipPath(
clipBehavior: Clip.hardEdge,
child: SlideTransition(
position: _offsetAnimation,
child: content,
),
),
);
}
try this
final Widget content = SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(child: Text('TEXT 1'),),
Expanded(child: Text('TEXT 2'),),
],
),
);
I was able to fix it with OverflowBox.
final Widget content = OverflowBox(
maxWidth: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('TEXT 1'),
Text('TEXT 2')
],
),
);
Maybe someone will help this solution
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.
I'm trying to get a header image to show on a page of an app but it's not showing up and the _header seems to be greyed out in my code. I'm missing something I guess that I'm unsure of. Edit: I need the header to show above the rows of content in the build.
Widget _header() {
return new Container(
child: new Row(
children:<Widget>[
new Column(
children: <Widget>[
Image.asset(
'assets/classes-Image.png',
),
],
),
],
),
);
}
Extra code below:
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: const Text('Learn How to Paint'),
backgroundColor: Color(0xFF202945),
),
body: new Container(
child: ListView(
shrinkWrap: true,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Column(
children: <Widget>[
Row(
children: <Widget>[
new Padding(
padding: const EdgeInsets.only(
left: 20.0,
),
),
Image.asset(
'assets/Profile-Photo.png',
),
new Padding(
padding: const EdgeInsets.only(
right: 20.0,
),
),
Text(
'Katherine G.',
),
],
),
],
),
```
You can achieve this by placing your header widget right before the Row widget.
The header is not showing because you didn't add it in the ListView.
I hope this solves your issue.
You need to be calling _header() from somewhere in your build function and give the result as a child to another widget. It being grayed out probably means you're not calling it.
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...
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: