【问题标题】:Flutter - How does Column constrain its height inside a ListView when its default mainAxisSize = max?Flutter - 当默认 mainAxisSize = max 时,Column 如何限制其在 ListView 内的高度?
【发布时间】:2021-06-16 11:19:39
【问题描述】:

什么魔法让 ListView 在布局期间将其子项限制为它们的最小固有大小?


根据Columnlayout algorithm,它会尝试尽可能高(默认)。

ListView 内,在performLayout 期间,Sliver 孩子的高度限制是double.INFINITY(如果我没记错的话)。

ListView 内的传入高度约束为无穷大时,Column 如何将其高度限制为其固有高度(即包含其子项所需的最小值)?

这是我尝试理解的示例代码。

在注释掉child:ListView() 的同时取消注释child: MyColumn() 会显示Column 扩展到其通常的最大高度。但在ListView 内部,它神奇地被限制在其最小高度。我想知道这是怎么做到的。

import 'package:flutter/material.dart';

class FlexInListViewPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Column in ListView'),
      ),
      body: Container(
        decoration: BoxDecoration(
          border: Border.all(width: 3, color: Colors.lightGreenAccent)
        ),
        //child: MyColumn() // ← uncomment while commenting out ↓ to see Column & its default height
        child: ListView(// imposes tight constraint of screen width to children
          children: [ /// RenderSliverList performLayout doesn't impose a constraint height during layout
            /// but asks children to report back size after layout complete
            /// this allows ListView to pass a height constraint to Column
            Container(child: Text('child'), color: Colors.yellowAccent,),
            Container(child: MyColumn(), color: Colors.orangeAccent.withOpacity(.5),)
          ],
        ),
      ),
    );
  }
}

class MyColumn extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    /// Column
    /// 1: layout fixed-height (zero flex factor) children in unbounded vertical space
    /// 2: Calculate/reserve remaining space for flex-height children
    /// 3: No flex children, skip flex-kids layout
    /// 4: Width is either widest child, or width imposed by parent (ListView: screen width)
    /// 5: Height of Column is by default mainAxisSize: max, try to fill all vert. space
    /// 5: If mainAxisSize: min & incoming vert. constraints allow,
    /// height of Column is sum of children heights
    return Column(
      children: [
        Container(child: Text('inside Column'), color: Colors.lightBlueAccent.withOpacity(.3),)
      ],
    );
  }
}

以上代码呈现的内容:

注意事项

我已经看到parentUsesSize 的代码,其中布局大小从子级报告到父级,但我不明白Column 在其约束不受限制时如何将自身调整为最小高度。是否传递了一些不明显的信息,例如“最小所需布局大小”与“所需布局大小”?

【问题讨论】:

    标签: flutter


    【解决方案1】:

    我假设这是您想要实现的目标, 在您的 ListView 中添加 shrinkWrap: trueprimary: false

    ListView(// imposes tight constraint of screen width to children
                primary: false,
                shrinkWrap: true,
                children: [ /// RenderSliverList performLayout doesn't impose a constraint height 
                during layout
                /// but asks children to report back size after layout complete
                /// this allows ListView to pass a height constraint to Column
                Container(child: Text('child'), color: Colors.yellowAccent,),
                Container(child: MyColumn(), color: Colors.orangeAccent.withOpacity(.5),)
              ],
    

    【讨论】:

    • 感谢您的回复,但我并不是要减小 ListView 的大小。我正在寻找关于 Column 如何扩展以占据整个 ListView 的解释,据我所知,根据其布局算法,默认情况下应该这样做。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    • 2014-12-03
    • 2020-07-23
    • 2020-06-23
    • 2011-07-26
    • 2020-05-22
    相关资源
    最近更新 更多