119

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.

Mary
  • 18,347
  • 23
  • 59
  • 76

11 Answers11

167

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
  ],
);
Pedro Massango
  • 4,114
  • 2
  • 28
  • 48
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
127

The easiest and the correct way to do it - use Spacer()

Example:

Column(
    children: [
      SomeWidgetOnTheTop(),
      Spacer(),
      SomeCenterredBottomWidget(),
    ],
);
Andrew
  • 36,676
  • 11
  • 141
  • 113
  • 12
    not working if column in SingleChildScrollView – evals Feb 26 '21 at 16:53
  • 4
    @evals How to use Spacer() in the case of parent being SingleChildScrollView() ? – zackygaurav Mar 16 '21 at 15:12
  • 2
    Nice. Spacer() is equals to Expanded(child: Container()) – Huy Nguyen Jun 27 '21 at 06:50
  • Spacer doesn't work if you want other widgets of the column to be in the center and just one at the bottom – who-aditya-nawandar Dec 10 '21 at 16:19
  • @who-aditya-nawandar No, it works. I use `.center` for both of `mainAxisAlignment` and `crossAxisAlignment` parameter inside the `Column` widget. The children which has to be in the center, i wrap it using `Center`. And i use `Spacer` between of the `Center`. So the order inside `Column` is: `Spacer`, `Center`, `Spacer`, `YourWidget` – Muhammad Faisal Aug 29 '23 at 04:04
76
Expanded(
  child: Align(
    alignment: FractionalOffset.bottomCenter,
      child: Padding(
        padding: EdgeInsets.only(bottom: 10.0),
          child: //Your widget here,
    ),
  ),
),
Lucas Macêdo
  • 23
  • 1
  • 7
Abhijith Brumal
  • 1,652
  • 10
  • 14
43

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

enter image description here

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)
              ),
            )
          ],
        ),
      ),
Ikar Pohorský
  • 4,617
  • 6
  • 39
  • 56
Tushar Pandey
  • 4,557
  • 4
  • 33
  • 50
27

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.

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
Mary
  • 18,347
  • 23
  • 59
  • 76
13

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.
Smily
  • 2,732
  • 1
  • 15
  • 20
  • Spacer ... dead simple solution. Thx. My tree is: Scaffold > Container > Column > [ItemAtTop, Spacer, ItemAtBottom]. Now ItemAtTop is at top, ItemAtBottom is always at bottom. – MrToast Jun 23 '23 at 10:56
13

Design everything using Expanded() is one of the easiest way to do thisenter image description here

Column(
            children: [
              Expanded(
                child: Placeholder(),
                flex: 1,
              ),
              Expanded(
                child:  Placeholder(),
                flex: 10,
              ),
              Expanded(
                flex: 2,
                child: Placeholder(),
              )
            ],
          ),
Bawantha
  • 3,644
  • 4
  • 24
  • 36
9

If you wish to leave content as it, can wrap it with scrollable.

Useful if you have inputs in the children:

enter image description here

    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,
          ),
        )
      ],
    );
Adelina
  • 10,915
  • 1
  • 38
  • 46
4
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),
              ),
            ],
          ),
        ),
      ],
    );
  }
O Thạnh Ldt
  • 1,103
  • 10
  • 11
3

Wrap your Container in SingleChildScrollView() widget. Then it will not come above when keyboard pops up.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
1

In addition of Stack: to avoid floating container on keyboard, use this

return Scaffold(
    appBar: getAppBar(title),
    resizeToAvoidBottomInset: false,
    body:
Akshay
  • 85
  • 7