64
votes

I want to align a Flutter widget within its parent. I know that I can center a widget by wrapping it in a Center widget.

  Center(
    child: Text("widget"),
  )

But how do I align it to the right, bottom, top middle, etc?

Notes:

I am talking about a single child, not multiple children in a Row or Column. See these SO questions:

This one is on the right track but I am trying to make a more cannonical question:

3

3 Answers

130
votes

How to align widgets

To align a child widget within its parent you use the Align widget. If you know how to use the Center widget then you are the right track because Center is just a special case of Align.

Wrap the widget you wish to align with the Align widget and set its alignment property. For example, this would align a text widget to the middle right of the parent.

Align(
  alignment: Alignment.centerRight,
  child: Text("widget"),
)

Other options are

  • Alignment.topLeft
  • Alignment.topCenter
  • Alignment.topRight
  • Alignment.centerLeft
  • Alignment.center
  • Alignment.centerRight
  • Alignment.bottomLeft
  • Alignment.bottomCenter
  • Alignment.bottomRight

Here is what that looks like:

enter image description here

You are not limited to these locations. You can align your widget anywhere. by specifying an x,y pair, where (0,0) is the center of the view and the edges are 1.0 unit around it. Maybe an image would help:

alignment

where for any relative position (x,y)

  • Alignment.topLeft is Alignment(-1.0, -1.0)
  • Alignment.topCenter is Alignment(0.0, -1.0)
  • Alignment.topRight is Alignment(1.0, -1.0)
  • Alignment.centerLeft is Alignment(-1.0, 0.0)
  • Alignment.center is Alignment(0.0, 0.0)
  • Alignment.centerRight is Alignment(1.0, 0.0)
  • Alignment.bottomLeft is Alignment(-1.0, 1.0)
  • Alignment.bottomCenter is Alignment(0.0, 1.0)
  • Alignment.bottomRight is Alignment(1.0, 1.0)

Notice in the image that the alignment (x,y) doesn't need to be within the range [-1, +1]. The alignment (1,2) means it is at the right side of the widget and below the widget half again as much as its height.

Here is an example of a custom alignment position.

Align(
  alignment: Alignment(0.7, -0.5),
  child: Text("widget"),
)

alignment

Supplemental code

Here is the main.dart code used to make the above examples for your cut-and-paste convenience.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: myLayoutWidget(),
      ),
    );
  }
}

Widget myLayoutWidget() {
  return Align(
    alignment: Alignment(0.7, -0.5),
    child: Text(
      "widget",
      style: TextStyle(fontSize: 30),
    ),
  );
}
18
votes
  Expanded(
    child: Align(
      alignment: Alignment.centerRight,
      child: Text("widget"),
    ),
  )
3
votes

You can use Positioned and Align with Stack widget

A Stack allows you to stack elements on top of each other, with the last element in the array taking the highest prority. You can use Align, Positioned or Container to position the children of a stack.

Align

Widgets are moved by setting the alignment with Alignment, which has static properties like topCenter, bottomRight, and so on. Or you can take full control and set Alignment(1.0, -1.0), which takes x,y values ranging from 1.0 to -1.0, with (0,0) being the center of the screen.

Stack(
    children: [
        MyWidget(),
        Align(
            alignment: Alignment.topCenter,
            child: MyWidget(),
        ),
        Container(
            alignment: Alignment(-0.9, -0.9),
            child: MyWidget(),
        )  
    ]
);

Positioned

As an alternative to align, you can position children relative to the parent widget.

ConstrainedBox(
  constraints: BoxConstraints.tight(Size(double.infinity, 256)),
  child: Stack(
    alignment: AlignmentDirectional.center,
    children: <Widget>[
      Positioned(
        top: 0.0,
        child: Icon(Icons.calendar_today,
            size: 128.0, color: Colors.lightBlueAccent),
      ),
      Positioned(
          top: 4,
          right: 110,
          child: CircleAvatar(radius: 16, backgroundColor: Colors.red)),
    ],
  ),
)

enter image description here