在 Flutter 中,如何调整垂直布局,混合列和列表视图行为?

In Flutter, how can I have an adjusting vertical layout, a mix between column and listview behavior?

据我所知,Column 和 ListView 在用于基本根布局时都有非常不同的用法。

Column 在屏幕组件较少时使用(例如登录屏幕)。我们可以添加一些 Expanded 组件来调整中间的空白,这样当键盘可见时,屏幕会缩小以保持所有内容可见。

当屏幕有许多可能需要滚动的组件时,使用 ListView。我们不能在 ListView 中使用 Expanded 组件。使用ListView时,出现键盘不会改变空格,只会改变外部ListView的大小,而内部内容被滚动视图包裹。

现在的问题是,如果我想要这样的屏幕怎么办:

在 Flutter 中可以实现吗?怎么样?

编辑:根据 Reign 的评论,我从 SingleChildScrollView manual 中分离了一些代码,但如果它的子项包含 Expanded,它看起来仍然无法处理。

Widget columnRoot({
  MainAxisAlignment mainAxisAlignment = MainAxisAlignment.spaceBetween,
  AssetImage backgroundImage,
  List<Widget> children
}) =>
    LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) =>
        SingleChildScrollView(
            child: ConstrainedBox(
                constraints: BoxConstraints(
                  minHeight: viewportConstraints.maxHeight,
                ),
                child: Container(
                  decoration: BoxDecoration(
                      image: DecorationImage(
                          image: backgroundImage,
                          fit: BoxFit.cover),
                      color: Colors.white
                  ),
                  child: Column(
                      mainAxisSize: MainAxisSize.min,
                      mainAxisAlignment: mainAxisAlignment,
                      children: children
                  ),
                )
            )
        )
    );

Widget content(BuildContext context) => columnRoot(children: [
  Container(color: Colors.red, height: 100.0),
  Expanded(Container(color: Colors.green)), // without this line, there's no layout error
  Container(color: Colors.blue, height: 100.0),
]);

错误:

RenderFlex children have non-zero flex but incoming height constraints are unbounded.

我添加了一些您可以测试的代码,并附有一些解释。

复制粘贴并运行代码

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: SingleChildScrollView( //Since setting it to scrollable, your widget Column with expanded children wont work as it supposed to be because it wont know its parent height
        //Since its already scrollable `Expanded` will expand or shrink now based on it child widget (Expanded(child: SomeHeight widget)) refer: #10 example
          child: IntrinsicHeight( //This will fix the expanded widget error
            child: Container(
              //Test remove this height
              // height: 400, //But when you set its height before its parent scroll widget, `Expanded` will expand based on its available space 
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                mainAxisSize: MainAxisSize.max,
                children: [
                  Container(color: Colors.red, height: 100.0),
                  //#10
                  //Experiment with this
                  Expanded(
                    child: Container(
                      color: Colors.purple,
                      // height: 100.0, //initialized height, remove parent container height: 400
                      // child: Text("This is also considered as min height"),
                    ),
                  ),
                  Container(color: Colors.blue, height: 100.0),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}