我有一个列小部件与两个TextField小部件作为孩子,我想在他们之间有一些空间。

我已经尝试过mainAxisAlignment: mainAxisAlignment。但结果不是我想要的。


你可以在这两个小部件之间使用Padding小部件,或者用Padding小部件包装这些小部件。

更新

SizedBox小部件可以在两个小部件之间使用,以增加两个小部件之间的空间,它使代码比填充小部件更具可读性。

Ex:

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

只需要像这样用填充物把它包起来:

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

你也可以使用Container(padding…)或SizeBox(height: x.x)。最后一种是最常见的,但这取决于你想如何管理小部件的空间,如果空间确实是小部件的一部分,我喜欢使用填充,例如列表使用sizebox。


你可以在小部件之间放置一个具有特定高度的sizebox,如下所示:

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

为什么宁愿这样包装小部件在填充?可读性!有更少的可视化样板,更少的缩进和代码遵循典型的阅读顺序。


您可以使用Wrap()小部件代替Column()在子小部件之间添加空格。并使用spacing属性给予子元素之间相等的间距

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')
  ]
)

与上面为了代码可读性而使用sizebox的方式相同,您可以以相同的方式使用Padding小部件,而不必使其成为Column的任何子部件的父小部件

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

Column(
  children: <Widget>[
    FirstWidget(),
    Spacer(),
    SecondWidget(),
  ]
)

Spacer创建一个可插入到[flexible]小部件的灵活空间。(像一列)


你可以用不同的方法来解决这个问题。

如果使用行/列,则必须使用mainAxisAlignment: MainAxisAlignment.spaceEvenly 如果你使用Wrap Widget,你必须使用runSpacing: 5, spacing: 10日, 在任何地方都可以使用SizeBox()


有很多方法可以做到这一点,我在这里列出了一些。

Use SizedBox and provide some height: Column( children: <Widget>[ Widget1(), SizedBox(height: 10), // <-- Set height Widget2(), ], ) Use Spacer Column( children: <Widget>[ Widget1(), Spacer(), // <-- Spacer Widget2(), ], ) Use Expanded Column( children: <Widget>[ Widget1(), Expanded(child: SizedBox.shrink()), // <-- Expanded Widget2(), ], ) Set mainAxisAlignment Column( mainAxisAlignment: MainAxisAlignment.spaceAround, // <-- alignments children: <Widget>[ Widget1(), Widget2(), ], ) Use Wrap Wrap( direction: Axis.vertical, spacing: 20, // <-- Spacing between children children: <Widget>[ Widget1(), Widget2(), ], )


Column(children: <Widget>[
   Container(margin: EdgeInsets.only(top:12, child: yourWidget)),
   Container(margin: EdgeInsets.only(top:12, child: yourWidget))
]);

默认情况下没有高度, 您可以将列包装到容器中,并将特定高度添加到容器中。 然后你可以像下面这样使用:

Container(
   width: double.infinity,//Your desire Width
   height: height,//Your desire Height
   child: Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
         Text('One'),
         Text('Two')
      ],
   ),
),

您可能必须在列的子列之间使用sizebox()小部件。 希望这对你们有用


在这种情况下,大小框将不起作用,手机处于横向模式。

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),
            ),
          ),
        ),
      ],
     )

还可以使用辅助函数在每个子元素之后添加空格。

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

因此,返回的列表可以用作列的子元素

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'),
    ],
  ),
);

我不确定,如果它是错误的或有一个性能惩罚运行的孩子通过一个帮助函数为相同的目标?


我在这里没有看到这个解决方案,所以为了完整起见,我将把它贴出来。

你也可以使用map用Padding包裹子元素:

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

这是另一个涉及for循环的选项。

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.
        ])
  ],
),

你可以试试这个:


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,
        );
}

并调用


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

您可以使用Padding来包装每个子部件,然后设置Padding的顶部或底部。

如果你不想写很多相同的数字,你可以这样写:

Column(
  children: [
    child1, 
    child2, 
    ..., 
    childN
  ].map((e) => Padding(padding: EdgeInsets.only(top: 10), child: e)).toList()
);

如果你不想包装填充与每个小部件或重复大小框。

试试这个:

Column(
        children: [
          Widget(),
          Widget(),
          Widget(),
          Widget(),
        ]
            .map((e) => Padding(
                  child: e,
                  padding: const EdgeInsets.symmetric(vertical: 10),
                ))
            .toList(),
      ),

这将扭曲所有的小部件与填充没有重复。


我也希望在Flutter中有一些内置的方法来做到这一点。就像一个参数,你可以传递给列或行。有时你不希望每个元素都有填充,但希望元素之间有空格。特别是如果你有两个以上的孩子,写这样的东西有点乏味

const double gap = 10;
return Column(
  children: [
    Text('Child 1'),
    SizedBox(height: gap),
    Text('Child 2'),
    SizedBox(height: gap),
    Text('Child 3'),
    SizedBox(height: gap),
    Text('Child 4'),
  ],
);

然而,我想出了一个快速(不完美)的解决方案:

在你的项目中添加这个(只有一次):

extension ListSpaceBetweenExtension on List<Widget> {
  List<Widget> withSpaceBetween({double? width, double? height}) => [
    for (int i = 0; i < this.length; i++)
      ...[
        if (i > 0)
          SizedBox(width: width, height: height),
        this[i],
      ],
  ];
}

从现在开始,只要你有行或列,你就可以写

Column(
  children: [
    Text('Child 1'),
    Text('Child 2'),
    Text('Child 3'),
    Text('Child 4'),
  ].withSpaceBetween(height: 10),
),

当使用Row时,你必须用width替换height。


最好使用Wrap小部件,而不是列或行。

包装( 间距:10, runSpacing: 10, 孩子们:[], )


列小部件没有自己的高度,它只是随着我们在子小部件中添加的内容而展开。 如果你需要在多个小部件之间保持相同的空间,

Container(
   width: double.infinity,
   height: height,
   child: Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
         Text('One'),
         Text('Two'),
         Text('Three'),
         Text('Four')
      ],
   ),
),

或者使用SizeBox、Spacer或widget在它们之间添加自定义空间, 像这样

Column(
   children: <Widget>[
         Text('One'),
         SizedBox(height: 20), 
         Text('Two'),
         SizedBox(height: 40), 
         Text('Three'),
         SizedBox(height: 30), 
         Text('Four')
   ],
 ),

将输入字段小部件提取到一个自定义小部件中,该小部件包装在填充或带有填充的容器中(假设间隔对称)。

在每个子列之间设置大小不同的盒子(如其他回答中建议的那样)是不实际或不可维护的。如果你想改变间距,你必须改变每个大小的盒子小部件。

// An input field widget as an example column child
class MyCustomInputWidget extends StatelessWidget {
  const MyCustomInputWidget({Key? key})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    // wrapping text field in container
    return Container(
      // here is the padding :)
      padding: EdgeInsets.symmetric(vertical: 10),
      child: TextField(...)
    );
  }
}

...然后父类中的列

column(
  children: <Widget>[
    MyCustomInputWidget(),
    SizedBox(height: 10),
    MyCustomInputWidget(),
  ],
),

显然,您希望自定义小部件具有某种构造函数来处理不同的字段参数。


受https://stackoverflow.com/a/70993832/14298786的启发,在List<Widget>上使用扩展来添加sizebox:

extension on List<Widget> {
  List<Widget> insertBetweenAll(Widget widget) {
    var result = List<Widget>.empty(growable: true);
    for (int i = 0; i < length; i++) {
      result.add(this[i]);
      if (i != length - 1) {
        result.add(widget);
      }
    }
    return result;
  }
}

像这样使用:

Column(children: [
  Widget1(),
  Widget2(),
  Widget3(),
].insertBetweenAll(SizedBox(height: 20)))

如果在列、行、listView等中有太多的子元素,并且必须在应用程序的许多地方执行相同的操作,那么添加多个大小的框将变得乏味。

你可以使用下面的utils来封装添加这些大小的盒子的逻辑:

List<Widget> addHorizontalSpaceBetweenElements(double space, List<Widget> widgets) {
  return _addSpaceBetweenElements(widgets, () => SizedBox(width: space));
}

List<Widget> addVerticalSpaceBetweenElements(double space, List<Widget> widgets) {
  return _addSpaceBetweenElements(widgets, () => SizedBox(height: space));
}

List<Widget> _addSpaceBetweenElements(List<Widget> widgets, ValueGetter<SizedBox> sizedBoxGetter) {
  if (widgets.isEmpty || widgets.length == 1) {
    return widgets;
  }
  List<Widget> spacedWidgets = [widgets.first];
  for (var i = 1; i < widgets.length - 1; i++) {
    spacedWidgets.add(sizedBoxGetter());
    spacedWidgets.add(widgets[i]);
  }
  spacedWidgets.add(sizedBoxGetter());
  spacedWidgets.add(widgets.last);
  return spacedWidgets;
}


你可以这样使用它们:

Column(
  children: addVerticalSpaceBetweenElements(5, [
    Text(),
    Text(),
  Row(children: addHorizontalSpaceBetweenElements(5, [
    Text(),
    Text(),
  ])),
  ]));