How to align Column's children in different positions in Flutter? - flutter

How to achieve the following design in Flutter?
I'm trying to position a Card and a Button within a Column.
The Card must be positioned centered in the Column wihtout taking into consideration the height of the Button.
And the Button must be positioned at the bottom of the Column.

This is how you can do it using Stack
Stack(
children: <Widget>[
Center(
child: SizedBox(
height: 200.0,
width: 200.0,
child: Card(
elevation: 10.0,
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: MaterialButton(
child: Text("Button"),
color: Colors.grey,
minWidth: MediaQuery.of(context).size.width,
onPressed: () => null,
),
),
)
],
)

To answer the question's title (aligning items in a "Column" widget), you can do it with the Align widget:
Column(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Container(...),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(...),
),
],
)

Related

Move button to the bottom

I am trying to move the button to the bottom of the screen but in vain. I basically have 2 textEditingControllers and a button but the latter keeps sticking with the textEditingController. Any advice, please?
return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
physics: const ScrollPhysics(),
child: Column(
children: [
return Card(
elevation: 5,
clipBehavior: Clip.antiAlias,
margin: const EdgeInsets.all(0),
child: Container(
padding: const EdgeInsets.all(15),
child: Row(
children: [
Column(
),
Expanded(
child: Column(
children: [
LocationField(
isDestination: false,
textEditingController: sourceController),
LocationField(
isDestination: true,
textEditingController: destinationController),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: const EdgeInsets.all(5),
width: double.infinity,
child: ElevatedButton(
onPressed: () {},
child: const Text('Bottom Button '), // trying to move to the bottom
),
),
)
],
);
}
Where am I going wrong?
If you are in Scaffold and want to have some Button in a fixed position on the screen you can use floatingActionButton Property.
Example:
Scaffold(
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
floatingActionButton: Container(
height: 50,
margin: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {},
child: const Center(
child: Text('Hello'),
),
),
),
);
Of course floatingActionButton property is mainy used for FloatingActionButton but it's good to know that you can put there any widget (other types of buttons, Rows, Columns and others). For positioning this widget you can use 'floatingActionButtonLocation' Scaffold property.
Try below code
Column(
children: <Widget>[
Card(
elevation: 5,
clipBehavior: Clip.antiAlias,
margin: const EdgeInsets.all(0),
child: Container(
padding: const EdgeInsets.all(15),
child: Row(
children: [
Expanded(
child: Column(
children: [
Container(
width: 100,
height: 50,
color: Colors.red,
),
Container(
height: 50,
width: 100,
color: Colors.black,
),
],
),
),
],
),
),
),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: const EdgeInsets.all(5),
width: double.infinity,
child: ElevatedButton(
onPressed: () {},
child: const Text(
'Bottom Button '), // trying to move to the bottom
),
),
),
),
],
),
Result->
You can achieve it by making small changes in your code it self. you have to change the tree of your code as below.
Scaffold -> Body -> Column
Column First Child Should be wrapped with Expanded and then SinglechildScrollView then Column and remaining Widgets
And the Second Widget should be your Button.
This will make the Button to move to the end of the screen. I hope thats what you are trying to do.
But this way makes the Button visible on the screen all the time where as remaining widgets will be scrolling.

Centering a Row in a Stack

I have a widget that consists of a Row and an Icon in a stack. I want to center them both vertically in the stack (the row in the center, the icon in the right center). I wrap both widgets in an Align widget, but this only is affecting the Icon, not the Row. How can I have the ROw centered vertically?
This is my code
#override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.all(16.0),
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(searchLanguage == SearchLanguage.english ? word.english : word.korean,
style: Theme.of(context).textTheme.bodyText1),
SizedBox(
width: 8.0,
),
Icon(Icons.arrow_forward),
SizedBox(
width: 8.0,
),
Text(searchLanguage == SearchLanguage.english ? word.korean : word.english,
style: Theme.of(context).textTheme.bodyText1),
],
),
),
Align(
alignment: Alignment.centerRight,
child: IconButton(
icon: Icon(Icons.delete),
onPressed: () => deleteCallback(word),
),
)
],
),
),
);
}
This is the outcome
Try using the alignment of the stack instead:
Stack(
alignment: Alignment.topCenter,
Alignment properties works, also remove the unnecessary alignments
Full code:
return Card(
child: Padding(
padding: EdgeInsets.all(16.0),
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("One", style: Theme.of(context).textTheme.bodyText1),
SizedBox(
width: 8.0,
),
Icon(Icons.arrow_forward),
SizedBox(
width: 8.0,
),
Text("Two", style: Theme.of(context).textTheme.bodyText1),
],
),
Align(
alignment: Alignment.centerRight,
child: IconButton(
icon: Icon(Icons.delete),
onPressed: () {},
),
)
],
),
),
)

How to make a bottom bar with border radius using Card and add elevation to it in Flutter?

In my Flutter project, I have created a bottom bar using Container.
Here's the code given for that-
Scaffold(
body: Column(
children: <Widget>[
Container(
color: Colors.blue,
height: 300,
),
Expanded(
child: ListView(
shrinkWrap: true,
children: <Widget>[
getCarousel(),
Column(
children: <Widget>[
Container(
height: 240,
color: Colors.yellow,
),
Container(
color: Colors.teal,
height: 300,
),
],
),
Container(
height: 350,
width: double.infinity,
color: Colors.red,
child: ListView.builder(
scrollDirection: Axis.horizontal,
padding: new EdgeInsets.only(bottom: 72.0),
itemCount: itemList.length,
itemBuilder: (BuildContext context, int position) {
return new Column(
children: <Widget>[
Expanded(
child: new Container(
width: 160,
height: 320,
color: Colors.yellow[100],
),
),
new Divider()
],
);
},
),
),
],
),
),
Container(
height: 60,
width: double.maxFinite,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius:
BorderRadius.vertical(top: Radius.circular(20.0))),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
showBottomIcons(Icons.home, "Home", "/HomeScreen"),
showBottomIcons(
Icons.category, "Category", "/CategoryScreen"),
showBottomIcons(Icons.shopping_cart, "Cart", "/CartScreen"),
showBottomIcons(Icons.person, "Account", "/AccountScreen"),
],
),
)
],
),
)
The Output of the screen looks like that-
Now, I want to switch the Container to Card. But I got some problems-
Card is taking some by default padding and the border radius at two top corners are not working.
As the top two corners are rounded, the background is getting white(As you can see in image). I want that space red colored.
I need some elevation with border radius like below image using card-
& 3. You don't actually need card widget for this. You can add shadow on your container itself.
You have to use stack to achieve this.
As I am hoping you are using the same code as my previous answer of your another question. I have updated the answer with stack layout & your requirements
Container(
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Positioned.fill(
child: Container(
color: Colors.blue,
alignment: Alignment.center,
child: Text("Hello"),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 50,
width: double.maxFinite,
decoration: BoxDecoration(
boxShadow: [
new BoxShadow(
color: Colors.black,
blurRadius: 2.0,
),
],
color: Colors.yellow,
borderRadius:
BorderRadius.vertical(top: Radius.circular(20.0))),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_forward),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.arrow_downward),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.arrow_left),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.arrow_upward),
onPressed: () {},
),
],
),
),
)
],
),
)
editing steps for your code
I will try to explain the changes.
You have multiple items in your Column. Move everything except Container which you used as bottom bar (the last child of column) to another Column widget.
Put this last container child inside Align widget like my code
Put the newly created Column in Positioned.fill widget.
Change column of scaffold to Stack
Set this stack's fit property as StackFit.expand
The body of you Scaffold should look like this.
Stack(
fit: StackFit.expand,
children: <Widget>[
Positioned.fill(
child: Column(
children: <Widget>[
.... // Your page body childs
]
),
),
Align(
alignment: Alignment.bottomCenter,
child: ... // Your bottom bar container
)
]
)
To know more about stack visit here

How to align text in flutter with respect to a separator in middle?

How can I align text to the center with a separator as shown in the image:
It can be achieved using combination of Expanded and Align. Below one is the code which you can use to accomplish the same behavior.
Container(
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: Text("Test"),
),
),
Align(
alignment: AlignmentDirectional.center,
child: Center(
child: Text(" : "),
),
),
Expanded(
child: Align(
alignment: AlignmentDirectional.centerStart,
child: new Text("123"),
),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: Text("Test 123"),
),
),
Align(
alignment: AlignmentDirectional.center,
child: Center(
child: Text(" : "),
),
),
Expanded(
child: Align(
alignment: AlignmentDirectional.centerStart,
child: new Text("9337822"),
),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: Text("Test 123 123"),
),
),
Align(
alignment: AlignmentDirectional.center,
child: Center(
child: Text(" : "),
),
),
Expanded(
child: Align(
alignment: AlignmentDirectional.centerStart,
child: new Text("111888999999"),
),
),
],
),
],
),
)
Just give you logic because you didn't provide the relevant code and also you are new here.
Take Row Widget with three Text widgets as children as you can show in your image. Wrap 1st and 3rd Text with Expanded widget and set mainAxisAlignment: MainAxisAlignment.spaceBetween of Row Widget. And also you have to set alignment of all Text widgets like 1st has right, 2nd has center and 3rd has left alignment.
Thats it :)
~PS : You have to repeat for each row (Based on your image look), may be easy with List widget or etc.

Center Align Two Widgets in a Stack

Coming from Android development, what is the equivalent of 'android:layout_gravity="center_vertical"' in Flutter?
I have two boxes wrapped in a Stack that I would like to center align vertically. However, the size of the largest item is not fixed so I am unable to use any fixed values. This presents some difficulty as I have no way of positioning one child in relation to the other child. In Android, all you have to do is set 'layout_gravity' to 'center_vertical' on the child items.
This is what I have so far. The icon's position is fixed which is not good.
class CardItem extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new SizedBox(
width: double.infinity,
child: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(72.0, 6.0, 12.0, 6.0),
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: 150.0,
),
child: Material(
elevation: 8.0,
borderRadius: BorderRadius.circular(12.0),
color: Colors.white,
child: InkWell(
onTap: () => {},
child: Padding(
padding: EdgeInsets.fromLTRB(76.0, 24.0, 6.0, 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text('Computer',
style: Theme.of(context).textTheme.headline),
Text('电脑',
style: Theme.of(context).textTheme.subhead.apply(fontWeightDelta: -2)
),
],
),
),
),
),
)
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(12.0, 0.0, 0.0, 0.0),
child: SizedBox.fromSize(
size: Size.fromRadius(60.0),
child: Material(
elevation: 12.0,
shape: CircleBorder(),
child: Image.asset('image.png'),
),
),
),
),
],
)
);
}
}
Wrap it in an Align widget...
Align(
alignment: Alignment.center,
child: Positioned(
top: 10,
child: Text('hi'),
),
),