Center widget behavior relating to constraints

Viewed 124

Based on the Flutter Docs,

... This widget will be as big as possible if its dimensions are constrained and widthFactor and heightFactor are null. If a dimension is unconstrained and the corresponding size factor is null then the widget will match its child's size in that dimension. ...


Dummy code:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: LoginPage(),
    );
  }
}

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Container(
          //height: 100,
          child: Column(
            children: <Widget>[
              Center(
                child: Text('Logo'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Output: It simply prints "Logo" that is centered horizontally BUT not vertically.

This obeys the docs, "If a dimension is unconstrained ... match its child's size". In this case, Column has unbounded vertical constrains thus Center's incoming constraints are also unbounded. Thus Center matches height of Text widget and isn't centered vertically.


Dummy code(with comment uncommented): We run the exact same code but with the //height: 100, being uncommented.

What I thought should happen: Since now vertical dimension is constrained, I thought "Logo" would be both vertically and horizontally centered.

Actual output: Same output as previous dummy code.

Question: Why does this happen? According to the docs: "widget will be as big as possible ... are null" so shouldn't the Center widget be big as possible and center the child vertically and horizontally.


Sidenote: I only get the expected behavior of being centered horizontally and vertically if I remove the Column widget

1 Answers

The reason why this is happening is that Column's mainAxis which is the height is unbounded, therefore making Center match its child's height. Although you've constrained the Column's height to 100, its mainAxis is still unbounded. Think of Column like a ListView, although the ListView's height is bounded, it still allows its children to take more space than the available height.

Solutions:

  1. You could center your text widget by setting mainAxisAlignment to MainAxisAlignment.center
  2. Use Spacer()

Eg:

children: [
   Spacer(),
   Text(),
   Spacer(),
]
Related