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.
Related
I have a flutter app that I want to add "stories" to, but I am unable to do so cause I can't place 3 buttons over an image.
That's my desired look...
And this is what I can do so far...
And this is my code:-
child: GestureDetector(
child: Center(
child: Stack(
alignment: Alignment.bottomRight,
children: [
Image.network(
widget.url,
),
Container(
child: Column(children: [
Container(
color: Colors.grey,
child:
Column(children: [Icon(Icons.share), Text('مشاركة')]),
),
Container(
color: Colors.grey,
child:
Column(children: [Icon(Icons.share), Text('مشاركة')]),
),
Container(
color: Colors.grey,
child:
Column(children: [Icon(Icons.share), Text('مشاركة')]),
)
]),
)
],
),
),
onTap: () => controller.next(),
),
How can I achieve this effect?
Am I doing something with the Stack widget?
Using Positioned inside Stack can solve your problem, Below code may work for you, You can position the Container where you want it to be.
Widget build(BuildContext context) {
var ScreenHeight = MediaQuery.of(context).size.height;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Expenses App"),
backgroundColor: Colors.pink[900],
actions: [
IconButton(
icon: Icon(Icons.add),
// onPressed: () => startAddNewTransaction(context),
),
],
),
body: GestureDetector(
child: Center(
child: Stack(
// alignment: Alignment.bottomRight,
children: [
Image.network(
'https://picsum.photos/250?image=9',
),
Positioned(
top: ScreenHeight * 0.17,
child: Container(
child: Column(children: [
Container(
color: Colors.grey,
child:
Column(children: [Icon(Icons.share), Text('مشاركة')]),
),
SizedBox(height: ScreenHeight * 0.01),
Container(
color: Colors.grey,
child:
Column(children: [Icon(Icons.share), Text('مشاركة')]),
),
SizedBox(height: ScreenHeight * 0.01),
Container(
color: Colors.grey,
child:
Column(children: [Icon(Icons.share), Text('مشاركة')]),
)
]),
),
)
],
),
),
// onTap: () => controller.next(),
),
),
);
}
The default mainAxisSize of Column is max, If you set MainAxisSize.min for all Column you will get Stack's alignment.
child: Column(
mainAxisSize: MainAxisSize.min,
As for the alignment of your desire UI, I prefer using Align widget to wrap the parent Column.
Align(
alignment: Alignment(-1, .5), //play with it
child: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
More about Align.
GestureDetector(
child: Center(
child: Stack(
children: [
Container(
height: double.infinity,
width: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://st2.depositphotos.com/3759967/5593/i/600/depositphotos_55936567-stock-photo-swirling-frosty-multi-colored-fractal.jpg",
),
),
),
),
Positioned(
bottom: MediaQuery.of(context).size.height * 0.1,
child: Column(
children: [
Container(
margin: const EdgeInsets.only(bottom: 10.0),
color: Colors.grey,
child: Column(
children: const [Icon(Icons.share), Text('مشاركة')]),
),
Container(
margin: const EdgeInsets.only(bottom: 10.0),
color: Colors.grey,
child: Column(
children: const [Icon(Icons.share), Text('مشاركة')]),
),
Container(
margin: const EdgeInsets.only(bottom: 10.0),
color: Colors.grey,
child: Column(
children: const [Icon(Icons.share), Text('مشاركة')]),
)
]),
),
],
),
),
),
You can do like this, place image as background of a container, and your column in a positioned widget.
example
I am wondering why is it that my GridView is not rendering the widgets. I am trying to render the buttons in two columns and 2-3 rows.
The code is the following:
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
GridView.count(
shrinkWrap: true,
primary: true,
crossAxisCount: 2,
children: <Widget>[
Center(
child: FlatButton(
onPressed: () => {},
padding: EdgeInsets.all(10.0),
child: Column(children: <Widget>[
Image.asset(
'assets/img/wifi.png',
height: 50.0,
width: 50.0,
),
Text('Wifi')
]),
),
),
Center(
child: FlatButton(
onPressed: () => {},
padding: EdgeInsets.all(10.0),
child: Column(children: <Widget>[
Image.asset(
'assets/img/wifi.png',
height: 50.0,
width: 50.0,
),
Text('Key/Access')
]),
),
),
Center(
child: FlatButton(
onPressed: () => {},
padding: EdgeInsets.all(10.0),
child: Column(children: <Widget>[
Image.asset(
'assets/img/wifi.png',
height: 50.0,
width: 50.0,
),
Text('Key/Access')
]),
),
),
Center(
child: FlatButton(
onPressed: () => {},
padding: EdgeInsets.all(10.0),
child: Column(children: <Widget>[
Image.asset(
'assets/img/wifi.png',
height: 50.0,
width: 50.0,
),
Text('Key/Access')
]),
),
),
],
)
],
)));
}
}
I get an error, in the android emulator it renders yellow and black strips instead of the buttons with the corresponding images.
Wrap it with Container ( height: .. , width : double.infinity )
Or with SizedBox
Try removing the Column widget above the GridView
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 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(...),
),
],
)
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'),
),
),