275

In Android match_parent and wrap_content are used to resize the widgets automatically relative to their parent to the content the widget contains.

In Flutter it seems by default all widgets are set to wrap_content, how would I change it such that I can fill its width and height to that of its parent?

Faisal Abid
  • 8,900
  • 14
  • 59
  • 91

14 Answers14

463

Note: Default behaviour of parent widget is to fill all the space available with its child. Scafold>body:Container(sized) is different the Scafold>body:Center>Container(Sized) You can read more about it https://docs.flutter.dev/ui/layout/constraints

Understanding This will will clear all you concept how widget works : Constrains go down sizes go up parent set position

You can do with little Trick: Suppose you have requirement of : ( Width,Height )

Wrap_content ,Wrap_content :

 //use this as child
 Wrap(
  children: <Widget>[*your_child*])

Match_parent,Match_parent:

 //use this as child
Container(
        height: double.infinity,
    width: double.infinity,child:*your_child*)

Match_parent,Wrap_content :

 //use this as child
Row(
  mainAxisSize: MainAxisSize.max,
  children: <Widget>[*your_child*],
);

Wrap_content ,Match_parent:

 //use this as child
Column(
  mainAxisSize: MainAxisSize.max,
  children: <Widget>[your_child],
);
sourav pandit
  • 8,647
  • 2
  • 19
  • 17
  • 6
    to the match the parent you could also wrap your Widgets with SizedBox.expand() – Wecherowski Jan 03 '20 at 20:59
  • I do agree with all but one cases. `Wrap_content ,Wrap_content` one is handled by design by Flutter (which is great, you don't need to assign no _width_ nor _height_ every time). `Wrap` has different usage, explained here: https://www.youtube.com/watch?v=z5iw2SeFx2M – PrzemekTom Oct 19 '22 at 14:02
259

In order to get behavior for match_parent and wrap_content we need to use mainAxisSize property in Row/Column widget, the mainAxisSize property takes MainAxisSize enum having two values which is MainAxisSize.min which behaves as wrap_content and MainAxisSize.max which behaves as match_parent.

enter image description here

Link of the original Article

fluffyBatman
  • 6,524
  • 3
  • 24
  • 25
  • 19
    I would add that there's also the `crossAxisAlignment` field on Rows and Columns that can be set to `CrossAxisAlignment.stretch` to expand horizontally within a Column for example – wamfous Nov 28 '18 at 15:50
  • great answer! If anyone is looking for more such examples then use the following link https://medium.com/flutter-community/flutter-layout-cheat-sheet-5363348d037e – Swapnil Kadam Sep 27 '20 at 10:55
46

The short answer is that the parent doesn't have a size until the child has a size.

The way layout works in Flutter is that each widget provides constraints to each of its children, like "you can be up to this wide, you must be this tall, you have to be at least this wide", or whatever (specifically, they get a minimum width, a maximum width, a minimum height, and a maximum height). Each child takes those constraints, does something, and picks a size (width and height) that matches those constraints. Then, once each child has done its thing, the widget can can pick its own size.

Some widgets try to be as big as the parent allows. Some widgets try to be as small as the parent allows. Some widgets try to match a certain "natural" size (e.g. text, images).

Some widgets tell their children they can be any size they want. Some give their children the same constraints that they got from their parent.

Ian Hickson
  • 8,174
  • 1
  • 29
  • 22
  • 2
    Ian, when I have a `PageView` inside a `Column`, with another `Column` inside the current `page`, I get a rendering error, but I can fix it by wrapping the `PageView` inside an `Expanded` or a `Flexible`. The problem is, those 2 options only expand their child. Why isn't there related widget to shrink go fit, like "wrap content", for solving this kind of rendering issues? – Michel Feinstein Dec 11 '19 at 03:24
  • This behavior is similar to Android Jetpack Compose UI toolkit – MJ Studio Aug 24 '22 at 16:10
32

There are actually some options available:

You can use SizedBox.expand to make your widget match parents dimensions, or SizedBox(width: double.infinity) to match only the width or SizedBox(heigth: double.infinity) to match only the heigth.

If you want a wrap_content behavior it depends on the parent widget you are using, for example if you put a button on a column it will behave like wrap_content and to use it like match_parent you can wrap the button with a Expanded widget or a sizedbox.

With a ListView the button gets a match_parent behavior and to get a wrap_content behavior you can wrap it with a Flex widget like Row.

Using an Expanded widget makes a child of a Row, Column, or Flex expand to fill the available space in the main axis (e.g., horizontally for a Row or vertically for a Column). https://docs.flutter.io/flutter/widgets/Expanded-class.html

Using a Flexible widget gives a child of a Row, Column, or Flex the flexibility to expand to fill the available space in the main axis (e.g., horizontally for a Row or vertically for a Column), but, unlike Expanded, Flexible does not require the child to fill the available space. https://docs.flutter.io/flutter/widgets/Flexible-class.html

David H Moreno
  • 674
  • 5
  • 8
24

Use the widget Wrap.

For Column like behavior try:

  return Wrap(
          direction: Axis.vertical,
          spacing: 10,
          children: <Widget>[...],);

For Row like behavior try:

  return Wrap(
          direction: Axis.horizontal,
          spacing: 10,
          children: <Widget>[...],);

For more information: Wrap (Flutter Widget)

Farwa
  • 6,156
  • 8
  • 31
  • 46
14

I used this solution, you have to define the height and width of your screen using MediaQuery:

 Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width
  )
Ayoub Boumzebra
  • 3,885
  • 3
  • 21
  • 37
14

To make a child fill its parent, simply wrap it into a FittedBox

    FittedBox(
     child: Image.asset('foo.png'),
     fit: BoxFit.fill,
   )
Miraj Khandaker
  • 772
  • 10
  • 11
10

A simple workaround:

If a container has only one top level child, then you can specify alignment property for the child and give it any available value. it'll fill all the space in the container.

Container(color:Colors.white,height:200.0,width:200.0,
 child:Container(
    color: Colors.yellow,
    alignment:Alignment.[any_available_option] // make the yellow child match the parent size
   )
)

Another way:

Container(color:Colors.white,height:200.0,width:200.0,
 child:Container(
    color: Colors.yellow,
    constraints:  BoxConstraints.expand(height: 100.0), // height will be 100 dip and width will be match parent
   )
)
behzad besharati
  • 5,873
  • 3
  • 18
  • 22
10
Stack(
  children: [
    Container(color:Colors.red, height:200.0, width:200.0),
    Positioned.fill(
      child: Container(color: Colors. yellow),
    )
  ]
),
Mehmet Ali Bayram
  • 7,222
  • 2
  • 22
  • 27
  • 1
    Although your code might answer the question, a good answer should always explain what the code does and how it solves the problem. – BDL Jul 22 '19 at 08:07
  • 1
    this is not answer to wrap content. this is simply hard coded width and height. – Developine Dec 26 '19 at 07:32
8

Use FractionallySizedBox widget.

FractionallySizedBox(
  widthFactor: 1.0, // width w.r.t to parent
  heightFactor: 1.0,  // height w.r.t to parent
  child: *Your Child Here*
}

This widget is also very useful when you want to size your child at a fraction of its parent's size.

Example:

If you want the child to occupy 50% width of its parent, provide widthFactor as 0.5

mzaink
  • 261
  • 4
  • 10
5

Use this line of codes inside the Column. For wrap_content : mainAxisSize: MainAxisSize.min For match_parent : mainAxisSize: MainAxisSize.max

Naveen Aluri
  • 271
  • 3
  • 3
5

Match Parent

To match or fill the parent (height & width) we can use additional constraints on Container:

Container(
  constraints: BoxConstraints.expand(), // ← this guy
  child: Text('Center > Container > Text')
)

In Flutter, constraints are the space you can fill (or must fill, if "tight" constraints).

Constraints are given... no actually, imposed by parents.

By default, Container will wrap its content (child:) & size itself to its child, unless overriden (or not allowed by tight constraints).

Using the constraints: argument, we can give Container additional constraints to override default Container constraint behavior (such as wrapping content).

Using Container(constraints: BoxConstraints.something) doesn't overwrite incoming/parent constraints; It just allows us to override default behavior, where allowed, such as wrapping content.


Code Sample - BoxConstraints

Here's a copy/paste code example showing effects of various constraints we can apply to a Container that has "loose" incoming/parental constraints (provided by Center).

import 'package:flutter/material.dart';

class MatchParentPage extends StatefulWidget {
  @override
  _MatchParentPageState createState() => _MatchParentPageState();
}

class _MatchParentPageState extends State<MatchParentPage> {
  BoxConstraints constraints;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Match Parent'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Expanded( // shares space constraint evenly with other Expanded
            child: Center( // ← fills tight parent constraint & loosens ↓ child constraint ↓
              child: Container( // got loose constraint from Center... 
                  constraints: constraints, // can apply many additional constraints
                  color: Colors.lightBlueAccent.withOpacity(.3),
                  child: Text('Center > Container > Text')),
            ),
          ),
          Expanded(
            child: Container(
              color: Colors.orangeAccent,
                child: Wrap(
                    children: [
                      _button('default', null),
                      _button('*expand()', BoxConstraints.expand()),
                      _button('*tight(Size.infinite)', BoxConstraints.tight(Size.infinite)),
                      _button('tight(Size.zero)', BoxConstraints.tight(Size.zero)),
                      _button('tight(Size.fromHeight(100))', BoxConstraints.tight(Size.fromHeight(100))),
                      _button('tight(Size.fromWidth(100))', BoxConstraints.tight(Size.fromWidth(100))),
                      _button('tightForFinite(width: 100, height: 100)', BoxConstraints.tightForFinite(width: 100, height: 100)),
                      _button('loose(Size.infinite)', BoxConstraints.loose(Size.infinite)),
                      _button('tightFor(width: double.infinity)', BoxConstraints.tightFor(width: double.infinity)),
                      _button('tightFor(height: double.infinity)', BoxConstraints.tightFor(height: double.infinity)),
                    ])
            ),
          )
        ],
      ),
    );
  }

  Widget _button(String label, BoxConstraints _constraints) {
    bool _active = _constraints == constraints;
    return Padding(
      padding: const EdgeInsets.only(top:8, left: 8),
      child: RaisedButton(
        color: _active ? Colors.cyanAccent : null,
        child: Text(label),
        onPressed: () {
          setState(() => constraints = _constraints);
        },
      ),
    );
  }
}
Baker
  • 24,730
  • 11
  • 100
  • 106
5

MATCH_PARENT

enter image description here

FractionallySizedBox(
            widthFactor: 1.0, // width w.r.t to parent
            heightFactor: 1.0, // height w.r.t to parent

            child: ElevatedButton(
              onPressed: () {},
              child: Text("+"),
            ),
          )

OR

Container(
            height: double.infinity,
            width: double.infinity,
          child: ElevatedButton(
            onPressed: () {},
            child: Text("+"),
          ),
        )

OR

Container(
            height: MediaQuery.of(context).size.height,
            width: MediaQuery.of(context).size.width,
          child: ElevatedButton(
            onPressed: () {},
            child: Text("+"),
          ),
        )

OR

Container(
          constraints: BoxConstraints.expand(),
          child: ElevatedButton(
            onPressed: () {},
            child: Text("+"),
          ),
        )

WRAP_CONTENT

enter image description here

Wrap(children: [
          Container(
            child: ElevatedButton(
              onPressed: () {},
              child: Text("+"),
            ),
          ),
        ])

OR

Container(
          constraints: BoxConstraints.tightFor(),
          child: ElevatedButton(
            onPressed: () {},
            child: Text("+"),
          ),
        )

Match_parent,Wrap_content : enter image description here

Row(
            children: [
          Expanded(
            child: Container(
              child: ElevatedButton(
                onPressed: () {},
                child: Text("+"),
              ),
            ),
          ),
        ])

Wrap_content,Match_parent : enter image description here

Column(
            children: [
          Expanded(
            child: Container(
              child: ElevatedButton(
                onPressed: () {},
                child: Text("+"),
              ),
            ),
          ),
        ])
lava
  • 6,020
  • 2
  • 31
  • 28
0

For match parent option you can wrap your widget by a container and give it a width like this

width: double.infinity

this approach will make the widget fill max space available for it on the screen.

Michael
  • 411
  • 2
  • 6
  • 15