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 作为列表例如。
您可以在小部件之间放置一个带有特定 height
的 SizedBox
,如下所示:
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()
有很多种方法,我在这里列出一些。
使用SizedBox
并提供一些高度:
Column(
children: <Widget>[
Widget1(),
SizedBox(height: 10), // <-- Set height
Widget2(),
],
)
使用Spacer
Column(
children: <Widget>[
Widget1(),
Spacer(), // <-- Spacer
Widget2(),
],
)
使用Expanded
Column(
children: <Widget>[
Widget1(),
Expanded(child: SizedBox.shrink()), // <-- Expanded
Widget2(),
],
)
设置mainAxisAlignment
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, // <-- alignments
children: <Widget>[
Widget1(),
Widget2(),
],
)
使用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,然后设置top
或bottom
的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')
],
),
我有一个 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 作为列表例如。
您可以在小部件之间放置一个带有特定 height
的 SizedBox
,如下所示:
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 的使用方式与
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()
有很多种方法,我在这里列出一些。
使用
SizedBox
并提供一些高度:Column( children: <Widget>[ Widget1(), SizedBox(height: 10), // <-- Set height Widget2(), ], )
使用
Spacer
Column( children: <Widget>[ Widget1(), Spacer(), // <-- Spacer Widget2(), ], )
使用
Expanded
Column( children: <Widget>[ Widget1(), Expanded(child: SizedBox.shrink()), // <-- Expanded Widget2(), ], )
设置
mainAxisAlignment
Column( mainAxisAlignment: MainAxisAlignment.spaceAround, // <-- alignments children: <Widget>[ Widget1(), Widget2(), ], )
使用
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
:
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,然后设置top
或bottom
的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')
],
),