您的主要问题归结为想要在需要位于 ScrollView 中的 Column 中使用 Flex。您希望您的列在键盘未显示时填满整个页面,在显示键盘时根据需要删除尽可能多的空白空间,如果在删除所有空白空间后它仍然不适合剩余屏幕,则变为可滚动.
为此,您需要使用此页面中的最后一个示例:https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: IntrinsicHeight(
child: Column(
children: <Widget>[
Container(
// A fixed-height child.
color: const Color(0xff808000), // Yellow
height: 120.0,
),
Expanded(
// A flexible child that will grow to fit the viewport but
// still be at least as big as necessary to fit its contents.
child: Container(
color: const Color(0xff800000), // Red
height: 120.0,
),
),
],
),
),
),
);
},
);
}
您需要 LayoutBuilder,因为它提供了 viewportConstraints,它为您提供了孩子可以使用而不会溢出的最大高度。当键盘显示/隐藏时,它也会自动重建,因为这个值会改变。
您需要 SingleChildScrollView 能够在 Column 不再适合屏幕时滚动。
您需要 IntrinsicHeight 以便 Column 采用与其内容所需的高度完全相同的高度。没有这个,Column 会因为 ScrollView 占用无限高,Spacers 会抛出异常。
您需要 ConstrainedBox 来设置 Column 必须使用的最小高度 - 这是上面提到的值,来自 LayoutBuilder。这会强制 Column 至少与屏幕允许的一样大 - 如果没有这个,您的 Spacers 将不起作用,因为由于 InstrinsicHeight 小部件,Column 将缩小到其最小高度。
这可能有点难以理解,因为实现此布局需要大量用于不同目的的小部件,但好消息是您只需复制粘贴它并更改 Column 的内容。