SingleChildScrollview 中的 Flutter 包装行破坏了 spaceBetween
Flutter wrapping Row in SingleChildScrollview ruins spaceBetween
我有一个 Row
个按钮,它们的父级为 SingleChildScrollView
,水平。
包裹 SingleChildScrollView
后,行的元素不遵守 mainAxisAlignment
,特别是 space 之间,它们与不 space 之间...
如何使 spaceBetween 再次工作?
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: const [
TransportModeButton(
iconPath: 'images/icons/walking_icon.png',
text: 'Walking',
),
TransportModeButton(
iconPath: 'images/icons/bicycle_icon.png',
text: 'Bike & eScooter',
),
TransportModeButton(
iconPath: 'images/icons/public_transport_icon.png',
text: 'Public transport',
)
],
),
),
您可以通过将 Row
包裹在 BoxConstraints
中来解决它,例如:
Container(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: const [
Text("test1"),
Text("test2"),
Text("test3"),
],
),
)),
),
编辑:
要从 parents 中为您的 SingleChildsScrollView
获取约束,您可以使用 LayoutBuilder
来实现,因此代码如下所示:
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: constraints.maxWidth,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: const [
Text("test1"),
Text("test2"),
Text("test3"),
],
),
));
})
当您用 SCSV 包裹行时,行实际上没有宽度,因为它是无限的。
它不依赖于屏幕的宽度或任何其他宽度来计算space之间。
如果你真的想启用space,我会建议两种方式:
- 用 Container/SizedBox/BoxConstraints 包裹行并给它一个宽度。
- 要添加 SizedBox/用 Padding 包装您的 TransportModeButton,这将在按钮之间手动创建 spaces。
Row/Column 根据需要占用 space,这意味着如果需要且没有限制,它可以超出可用高度。
您的行占用了所需的 space,而不是更多。因此,MainAxisAlignment 实际上在工作(但不是我们想要的方式)。如果需要,请放置一个宽度为 space 的 SizedBox。
我的建议是,如果您知道有多少小部件可用并且您不只是为此使用整个屏幕,请使用 ListView。
单子滚动视图
Scaffold(
appBar: AppBar(),
body: SafeArea(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: const [
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
)
],
),
),
),
);
列表视图
Scaffold(
appBar: AppBar(),
body: SafeArea(
child: ListView(
scrollDirection: Axis.horizontal,
children: const [
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
],
),
),
);
无需使用singlechildscrollview
(SCSW) 来应对间隔场景。用户滚动磁贴似乎是一个糟糕的用户体验。您可以使用 softwrap
之类的东西让垂直流动。如果您仍想使用 SCSW,那么您可以尝试通过将 SCSW 的子项包装在 ConstrainedBox
.
中来对 SCSW 施加约束
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width)
我有一个 Row
个按钮,它们的父级为 SingleChildScrollView
,水平。
包裹 SingleChildScrollView
后,行的元素不遵守 mainAxisAlignment
,特别是 space 之间,它们与不 space 之间...
如何使 spaceBetween 再次工作?
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: const [
TransportModeButton(
iconPath: 'images/icons/walking_icon.png',
text: 'Walking',
),
TransportModeButton(
iconPath: 'images/icons/bicycle_icon.png',
text: 'Bike & eScooter',
),
TransportModeButton(
iconPath: 'images/icons/public_transport_icon.png',
text: 'Public transport',
)
],
),
),
您可以通过将 Row
包裹在 BoxConstraints
中来解决它,例如:
Container(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: const [
Text("test1"),
Text("test2"),
Text("test3"),
],
),
)),
),
编辑:
要从 parents 中为您的 SingleChildsScrollView
获取约束,您可以使用 LayoutBuilder
来实现,因此代码如下所示:
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: constraints.maxWidth,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: const [
Text("test1"),
Text("test2"),
Text("test3"),
],
),
));
})
当您用 SCSV 包裹行时,行实际上没有宽度,因为它是无限的。
它不依赖于屏幕的宽度或任何其他宽度来计算space之间。
如果你真的想启用space,我会建议两种方式:
- 用 Container/SizedBox/BoxConstraints 包裹行并给它一个宽度。
- 要添加 SizedBox/用 Padding 包装您的 TransportModeButton,这将在按钮之间手动创建 spaces。
Row/Column 根据需要占用 space,这意味着如果需要且没有限制,它可以超出可用高度。
您的行占用了所需的 space,而不是更多。因此,MainAxisAlignment 实际上在工作(但不是我们想要的方式)。如果需要,请放置一个宽度为 space 的 SizedBox。
我的建议是,如果您知道有多少小部件可用并且您不只是为此使用整个屏幕,请使用 ListView。
单子滚动视图
Scaffold(
appBar: AppBar(),
body: SafeArea(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: const [
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
)
],
),
),
),
);
列表视图
Scaffold(
appBar: AppBar(),
body: SafeArea(
child: ListView(
scrollDirection: Axis.horizontal,
children: const [
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
Icon(
Icons.nordic_walking,
size: 50,
),
SizedBox(
width: 20,
),
],
),
),
);
无需使用singlechildscrollview
(SCSW) 来应对间隔场景。用户滚动磁贴似乎是一个糟糕的用户体验。您可以使用 softwrap
之类的东西让垂直流动。如果您仍想使用 SCSW,那么您可以尝试通过将 SCSW 的子项包装在 ConstrainedBox
.
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width)