32

I am trying to get a container to be exactly half the screen height[after considering the AppBar height] and half the screen width.

This is what I came up with...

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Flexible(
            child: Container(
              width: MediaQuery.of(context).size.width / 2,
              color: Colors.red,
            ),
          ),
          Flexible(
            flex: 1,
            child: Container(),
          )
        ],
      ),
    );
  }
}

Is there a better way? current layout

Doc
  • 10,831
  • 3
  • 39
  • 63

5 Answers5

39

If you want the container's height to be the half of the available space, you can use LayoutBuilder widget. With LayoutBuilder widget, you can know inside the builder function what the max available width and height would be. The example usage in your case would be like this:

Scaffold(
      appBar: AppBar(),
      body: Align(
        alignment: Alignment.topCenter,
        child: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            return Container(
              height: constraints.maxHeight / 2,
              width: MediaQuery.of(context).size.width / 2,
              color: Colors.red,
            );
          },
        ),
      ),
    );
dshukertjr
  • 15,244
  • 11
  • 57
  • 94
  • 1
    Thanks man, your ` LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) ` helped me a lot to understand the basic of layout management.Thanks again. – Emon Sep 03 '20 at 01:46
  • 1
    Directly setting the width for the Container inside the Listview won't work, because the widget is automatically stretched to the full length of the screen. However, this method works... – Muhammad Faisal Jun 28 '23 at 05:07
31

The best way and simplest route to this and similar problems is simply by using FractionallySizedBox widget ; e.g

FractionallySizedBox(
    alignment: Alignment.topCenter,
    widthFactor: 0.5,
    child: Container(
    height: 100,
  ),
),

This widget (FractionallySizedBox) lets you build up your child by specifying the fraction of the parent width (or height) which is available to the child widget. After that , by specifying the alignment , you can specify the manner the rest of the space would be allocated.

For more help on this widget , please visit the offical help page of this widget.

Hossein Hadi
  • 1,229
  • 15
  • 20
21

You can deduct AppBar's height to configure Container size.

@override
Widget build(BuildContext context) {
  var appBar = AppBar();
  return Scaffold(
    appBar: appBar,
    body: Align(
      alignment: Alignment.topCenter,
      child: Container(
        height: (MediaQuery.of(context).size.height - appBar.preferredSize.height) / 2,
        width: MediaQuery.of(context).size.width / 2,
        color: Colors.red,
      ),
    ),
  );
}

Pete Houston
  • 14,931
  • 6
  • 47
  • 60
13

You are on the right track about using MediaQuery, but your code can be a lot simpler:

  Scaffold(
    appBar: AppBar(),
    body: Align(
      alignment: Alignment.topCenter,
      child: Container(
        height: MediaQuery.of(context).size.height / 2,
        width: MediaQuery.of(context).size.width / 2,
        color: Colors.red,
      ),
    ),
  );
dshukertjr
  • 15,244
  • 11
  • 57
  • 94
  • 1
    Ok, but this does not takes into account the height of AppBar, so the container is not exactly half in size. – Doc Jan 12 '19 at 09:54
4

Or just simply...

SizedBox(
          height: MediaQuery.of(context).size.height*0.5,
          child: ...,
        ),
Anurag Bhalekar
  • 830
  • 7
  • 9