Space 在 Flutter 中列的 children 之间

Space between Column's children in Flutter

我有一个 Column 小部件,其中有两个 TextField 小部件 children,我想在它们之间添加一些 space。

我已经试过了mainAxisAlignment: MainAxisAlignment.spaceAround,但结果不是我想要的

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

更新

SizedBox 小部件可以用在两个小部件之间以在两个小部件之间添加 space 并且它使代码比填充小部件更具可读性。

例如:

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

就这样用padding包起来:

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)。最后一个是最常见的,但它取决于您想如何管理小部件的 space,如果 space 确实是小部件的一部分,我喜欢使用填充,并使用 sizebox 作为列表例如。

您可以在小部件之间放置一个带有特定 heightSizedBox,如下所示:

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

为什么更喜欢这个而不是在 Padding 中包装小部件? 可读性!视觉样板更少,缩进更少,代码遵循典型的阅读顺序。

您可以使用 Wrap() 小部件代替 Column() 在子节点之间添加 space widgets.And 使用间距 属性 使子节点之间的间距相等

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

SizedBox 的使用方式与 出于代码可读性的目的,您可以以相同的方式使用 Padding 小部件,而不必将其作为 Column 的任何子级的父级小部件

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

Spacer 创建一个灵活的 space 以插入到 [灵活] 小部件中。 (点赞专栏)

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

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()

有很多种方法,我在这里列出一些。

  1. 使用SizedBox并提供一些高度:

     Column(
       children: <Widget>[
         Widget1(),
         SizedBox(height: 10), // <-- Set height
         Widget2(),
       ],
     )
    
  2. 使用Spacer

     Column(
       children: <Widget>[
         Widget1(),
         Spacer(), // <-- Spacer
         Widget2(),
       ],
     )
    
  3. 使用Expanded

     Column(
       children: <Widget>[
         Widget1(),
         Expanded(child: SizedBox.shrink()), // <-- Expanded
         Widget2(),
       ],
     )
    
  4. 设置mainAxisAlignment

     Column(
       mainAxisAlignment: MainAxisAlignment.spaceAround, // <-- alignments
       children: <Widget>[
         Widget1(),
         Widget2(),
       ],
     )
    
  5. 使用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))
]);

列默认没有高度, 您可以将 Column 包装到 Container 并将特定高度添加到 Container。 然后你可以使用类似下面的东西:

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

您可能必须在列的子项之间使用 SizedBox() 小部件。 希望有用

大小框在这种情况下无济于事,phone 处于横向模式。

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

您还可以使用辅助函数在每个 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();
}

那么,返回的list可以作为children的一列

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

我不确定它是错误的还是为了相同的目标通过辅助函数对 运行 children 造成性能损失?

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

您还可以使用 map:

将 children 换成 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包裹每个子widget,然后设置topbottom的Padding。

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

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

如果您不想用每个小部件包装 Padding 或重复 SizedBox。

试试这个:

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

这将扭曲所有带有填充的小部件而不重复。

我也希望 Flutter 中有一些 built-in 方法可以做到这一点。就像您可以传递给 Column 或 Row 的参数一样。有时你不想在每个元素周围填充,但你希望它们之间 space 。特别是如果你有两个以上的children,写一些像

这样的东西有点乏味
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 时,您必须将 'height' 替换为 'width'。

最好使用环绕小部件而不是列或行。

换行( 间距:10, 运行间距:10, children:[], )

列小部件没有自己的高度,它只是随着我们在子小部件中添加而展开。 因为如果您需要在多个小部件之间使用相同的 space,那么,

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

或者只是通过使用 SizeBox、Spacer 或小部件在它们之间添加自定义 space, 像这样

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