155
votes

I have a Column widget with two TextField widgets as children and I want to have some space between both of them.

I already tried mainAxisAlignment: MainAxisAlignment.spaceAround, but the result was not what I wanted.

17
Simply Put SizedBox( height: 15.0, ), Between the two TextField - anmol.majhail
margin: EdgeInsets.only(left: 200.0, top: 300.0)) - user7856586

17 Answers

213
votes

You can use Padding widget in between those two widget or wrap those widgets with Padding widget.

Update

SizedBox widget can be use in between two widget to add space between two widget and it makes code more readable than padding widget.

Ex:

Column(
  children: <Widget>[
    Widget1(),
    SizedBox(height: 10),
    Widget2(),
  ],
),
154
votes

You can put a SizedBox with a specific height between the widgets, like so:

Column(
  children: <Widget>[
    FirstWidget(),
    SizedBox(height: 100),
    SecondWidget(),
  ],
),

Why to prefer this over wrapping the widgets in Padding? Readability! There is less visual boilerplate, less indention and the code follows the typical reading-order.

78
votes

you can use Wrap() widget instead Column() to add space between child widgets.And use spacing property to give equal spacing between children

Wrap(
  spacing: 20, // to apply margin in the main axis of the wrap
  runSpacing: 20, // to apply margin in the cross axis of the wrap
  children: <Widget>[
     Text('child 1'),
     Text('child 2')
  ]
)
34
votes

Just use padding to wrap it like this:

Column(
  children: <Widget>[
  Padding(
    padding: EdgeInsets.all(8.0),
    child: Text('Hello World!'),
  ),
  Padding(
    padding: EdgeInsets.all(8.0),
    child: Text('Hello World2!'),
  )
]);

You can also use Container(padding...) or SizeBox(height: x.x). The last one is the most common but it will depents of how you want to manage the space of your widgets, I like to use padding if the space is part of the widget indeed and use sizebox for lists for example.

30
votes

There are many ways of doing it, I'm listing a few here.

  1. Use Container and give some height:

    Column(
      children: <Widget>[
        Widget1(),
        Container(height: 10), // set height
        Widget2(),
      ],
    )
    
  2. Use Spacer

    Column(
      children: <Widget>[
        Widget1(),
        Spacer(), // use Spacer
        Widget2(),
      ],
    )
    
  3. Use Expanded

    Column(
      children: <Widget>[
        Widget1(),
        Expanded(child: SizedBox()), // use Expanded
        Widget2(),
      ],
    )
    
  4. Use mainAxisAlignment

    Column(
      mainAxisAlignment: MainAxisAlignment.spaceAround, // mainAxisAlignment
      children: <Widget>[
        Widget1(),
        Widget2(),
      ],
    )
    
  5. Use Wrap

    Wrap(
      direction: Axis.vertical, // make sure to set this
      spacing: 20, // set your spacing
      children: <Widget>[
        Widget1(),
        Widget2(),
      ],
    )
    
9
votes
Column(
  children: <Widget>[
    FirstWidget(),
    Spacer(),
    SecondWidget(),
  ]
)

Spacer creates a flexible space to insert into a [Flexible] widget. (Like a column)

9
votes

I don't see this solution here, so just for the sake of completeness I'll post it.

You can also wrap children with Padding using map:

Column(
      children: [Text('child 1'), Text('child 2')]
          .map(
            (e) => Padding(
              padding: const EdgeInsets.all(8),
              child: e,
            ),
          )
          .toList(),
    );
7
votes

The same way SizedBox is used above for the purpose of code readability, you can use the Padding widget in the same manner and not have to make it a parent widget to any of the Column's children

Column(
  children: <Widget>[
    FirstWidget(),
    Padding(padding: EdgeInsets.only(top: 40.0)),
    SecondWidget(),
  ]
)
4
votes

There are many answers here but I will put here the most important one which everyone should use.

1. Column

 Column(
          children: <Widget>[
            Text('Widget A'), //Can be any widget
            SizedBox(height: 20,), //height is space betweeen your top and bottom widget
            Text('Widget B'), //Can be any widget
          ],
        ),

2. Wrap

     Wrap(
          direction: Axis.vertical, // We have to declare Axis.vertical, otherwise by default widget are drawn in horizontal order
            spacing: 20, // Add spacing one time which is same for all other widgets in the children list
            children: <Widget>[
              Text('Widget A'), // Can be any widget
              Text('Widget B'), // Can be any widget
            ]
        )
3
votes

You can solve this problem in different way.

If you use Row/Column then you have to use mainAxisAlignment: MainAxisAlignment.spaceEvenly

If you use Wrap Widget you have to use runSpacing: 5, spacing: 10,

In anywhere you can use SizeBox()

3
votes

Columns Has no height by default, You can Wrap your Column to the Container and add the specific height to your Container. Then You can use something like below:

Container(
   width: double.infinity,//Your desire Width
   height: height,//Your desire Height
   child: Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
         Text('One'),
         Text('Two')
      ],
   ),
),
1
votes
Column(children: <Widget>[
   Container(margin: EdgeInsets.only(top:12, child: yourWidget)),
   Container(margin: EdgeInsets.only(top:12, child: yourWidget))
]);
1
votes

You may have to use SizedBox() widget between your column's children. Hope that'll be usefull

1
votes

You can also use a helper function to add spacing after each child.

List<Widget> childrenWithSpacing({
  @required List<Widget> children,
  double spacing = 8,
}) {
  final space = Container(width: spacing, height: spacing);
  return children.expand((widget) => [widget, space]).toList();
}

So then, the returned list may be used as a children of a column

Column(
  children: childrenWithSpacing(
    spacing: 14,
    children: [
      Text('This becomes a text with an adjacent spacing'),
      if (true == true) Text('Also, makes it easy to add conditional widgets'),
    ],
  ),
);

I'm not sure though if it's wrong or have a performance penalty to run the children through a helper function for the same goal?

-1
votes

The sized box will not help in the case, the phone is in landscape mode.

body: Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        Expanded(
           child: Container(
            margin: EdgeInsets.all(15.0),
            decoration: BoxDecoration(
              color: Color(0xFF1D1E33),
              borderRadius: BorderRadius.circular(10.0),
            ),
          ),
        ),
        Expanded(
           child: Container(
            margin: EdgeInsets.all(15.0),
            decoration: BoxDecoration(
              color: Color(0xFF1D1E33),
              borderRadius: BorderRadius.circular(10.0),
            ),
          ),
        ),
        Expanded(
           child: Container(
            margin: EdgeInsets.all(15.0),
            decoration: BoxDecoration(
              color: Color(0xFF1D1E33),
              borderRadius: BorderRadius.circular(10.0),
            ),
          ),
        ),
      ],
     )
-1
votes

Here's another option involving a for loop.

Column(
  children: <Widget>[
    for (var i = 0; i < widgets.length; i++)
      Column(
        children: [
          widgets[i], // The widget you want to create or place goes here.
          SizedBox(height: 10) // Any kind of padding or other widgets you want to put.
        ])
  ],
),
-1
votes

You can try this :


import 'package:flutter/material.dart';

class CustomColumn extends Column {
  CustomColumn({
    Key? key,
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    TextDirection? textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline? textBaseline,
    List children = const [],
    EdgeInsetsGeometry? rowPadding,
  }) : super(
          children: children.map((e) => Padding(padding : rowPadding ?? EdgeInsets.only(bottom:12), child : e)).toList(),
          key: key,
          mainAxisAlignment: mainAxisAlignment,
          mainAxisSize: mainAxisSize,
          crossAxisAlignment: crossAxisAlignment,
          textDirection: textDirection,
          verticalDirection: verticalDirection,
          textBaseline: textBaseline,
        );
}

and call


CustomColumn(children: [
                    item1,
                    item2,
                    item3,
                  ])