【问题标题】:Flutter column fill space颤振列填充空间
【发布时间】:2020-09-01 11:02:08
【问题描述】:

我想做下面的白框来填充垂直空间,我设置了mainAxisAlignment: MainAxisAlignment.spaceBetween,我想把标题放在顶部,把描述放在白框的底部

我不想明确设置 white box 的高度,我只想强制它填充空间

Container(
          color: Colors.blueGrey,
          padding: EdgeInsets.all(8),
          margin: EdgeInsets.all(8),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Flexible(
                    child: Container(
                      color: Colors.white,
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          Text('Title'),
                          Text(
                            'Description Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been ',
                            style: TextStyle(fontSize: 10),
                          ),
                        ],
                      ),
                    ),
                  ),
                  Column(
                    children: <Widget>[
                      CircleAvatar(
                        child: Text('AH'),
                        backgroundColor: Colors.deepOrangeAccent,
                        radius: 50,
                      )
                    ],
                  ),
                ],
              ),
              Icon(Icons.email)
            ],
          ),
        ),

当前结果:

预期结果

我不是在寻找可行的解决方案!我正在学习颤振,我想知道为什么Row 不能扩展高度

【问题讨论】:

  • 你能分享一下你的预期结果吗?
  • 我添加了预期结果
  • 你可以尝试用Expanded 包裹你的Row 并检查它是否有效?
  • Expanded包裹Row后,blueGrey框填满了整个屏幕,我不想要它,但是白框有正确的视图
  • 尝试为 Row 赋予属性 crossAxisAlignment: CrossAxisAlignment.stretch

标签: flutter


【解决方案1】:
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: <Widget>[
    child: Expanded(
      child: Container(
        // Fill available Space.
        constraints: BoxConstraints.expand()
        color: Colors.white,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Text('Title'),
            Text('Description Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been ',
              style: TextStyle(fontSize: 10),
            ),
          ],
        ),
      ),
    ),
    // there was no need for the and additional column
    CircleAvatar(
      child: Text('AH'),
      backgroundColor: Colors.deepOrangeAccent,
      radius: 50
    ),
  ]
)

希望如此,它会起作用

【讨论】:

  • 不工作,错误:BoxConstraints 强制无限高。
【解决方案2】:

好问题!

解决方案是使用IntrinsicHeight并在Row中设置crossAxisAlignment: CrossAxisAlignment.stretch,在您的特定情况下您不需要设置对齐,我稍后会解释。

现在,IntrinsicHeight 在这里做什么可以解决您的问题?请看,当您向您的Row 提供IntrinsicHeight 时,它会强制Row 的子代占用最大的可用垂直空间,前提是您设置了crossAxisAlignment: CrossAxisAlignment.stretch 属性。

在您的情况下,Row 的两个孩子都是Column,第一列的高度比第二列短,设置IntrinsicHeight 后,您允许Columns 占用最大值可用空间,这里是 max(column1, column2) = column2。所以,第一列占据第二列的高度,如果第一列更大,第二列将占据第一高度,你明白了。

正如我之前提到的,您还需要设置crossAxisAlignment: CrossAxisAlignment.stretch 以在使用IntrinsicHeight 时允许此行为生效,但仅仅因为您将Column 用作Row 的子项,您可以跳过它,因为Column 试图占用整个可用的垂直空间,除非您设置了mainAxisSize: MainAxisSize.min,而您没有在RowColumn 中设置。

解决方案:

Container(
  color: Colors.blueGrey,
  padding: EdgeInsets.all(8),
  margin: EdgeInsets.all(8),
  child: Column(
    mainAxisSize: MainAxisSize.min,
    children: <Widget>[
      IntrinsicHeight( // 1st add this
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.stretch, // 2nd use this
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Flexible(
              child: Container(
                color: Colors.white,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    Text('Title'),
                    Text(
                      'Description Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been ',
                      style: TextStyle(fontSize: 10),
                    ),
                  ],
                ),
              ),
            ),
            Column(
              children: <Widget>[
                CircleAvatar(
                  child: Text('AH'),
                  backgroundColor: Colors.deepOrangeAccent,
                  radius: 50,
                )
              ],
            ),
          ],
        ),
      ),
      Icon(Icons.email)
    ],
  ),
)

【讨论】:

  • 谢谢,我有两个问题: 1- IntrinsicHeight 相对昂贵,因为它在最终布局阶段之前添加了一个推测布局通道,我想在不定式列表视图中使用我的小部件,有没有其他解决方案? 2- 为什么将crossAxisAlignment: CrossAxisAlignment.stretch 添加到Row 不起作用并且出现错误“BoxConstraints 强制无限高度。”
  • 1.是的,使用起来非常昂贵,如果你想在某种无限的布局中使用它,你应该给它一个固定的高度。 2. 我在当前代码中没有看到该错误。你能编辑你的帖子引发这个错误吗?
  • 当前代码没问题,我问如果我们删除IntrinsicHeight 并添加crossAxisAlignment: CrossAxisAlignment.stretch 我们有错误!为什么?
  • @WebMaster 是的,在这种情况下,您将不得不面对错误,因为一方面您说您要将Column(父级)的高度限制为MainAxisSize.min另一方面,您说您希望通过设置CrossAxisAlignment.stretch 来允许Row 的完整垂直空间可用性,它们相互矛盾,唯一使它们工作的解决方案是使用IntrinsicHeight,它允许@987654353 @'s children 扩展到 max_height(row_children)。
【解决方案3】:

刚刚通过用RowIntrinsicHeight 包装行来发现soln

这里是代码:

Container(
    color: Colors.blueGrey,
    padding: EdgeInsets.all(8),
    margin: EdgeInsets.all(8),
    child: Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        IntrinsicHeight(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Flexible(
                child: Container(
                  color: Colors.white,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      Text('Title'),
                      Text(
                        'Description Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been ',
                        style: TextStyle(fontSize: 10),
                      ),
                    ],
                  ),
                ),
              ),
              Column(
                children: <Widget>[
                  CircleAvatar(
                    child: Text('AH'),
                    backgroundColor: Colors.deepOrangeAccent,
                    radius: 50,
                  )
                ],
              ),
            ],
          ),
        ),
        Icon(Icons.email)
      ],
    ),
  ),

【讨论】:

【解决方案4】:

试试这个

body: Container(
        color: Colors.blueGrey,
        padding: EdgeInsets.all(8),
        margin: EdgeInsets.all(8),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Row(
              children: <Widget>[
                Expanded(
                  child: Container(
                    width: double.infinity,
                    color: Colors.white,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        Expanded(
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: <Widget>[
                              Text('Title'),
                              SizedBox(
                                height: 50,
                              ),
                              Text(
                                'Description Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been ',
                                style: TextStyle(
                                  fontSize: 10,
                                ),
                              ),
                            ],
                          ),
                        ),
                        Expanded(
                          child: Align(
                            alignment: Alignment.centerRight,
                            child: CircleAvatar(
                              child: Text('AH'),
                              backgroundColor: Colors.deepOrangeAccent,
                              radius: 50,
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
            Icon(Icons.email)
          ],
        ),
      ),

【讨论】:

  • 这不是我想要的。你把SizedBox(height: 50,)放在两个文本之间,我删除与否MainAxisAlignment.spaceBetween没有影响!!
  • @WebMaster: SizeBox() 用于增加两个小部件之间的距离,它不会在它们之间添加任何空间,在我这边它正在工作。
  • 我运行你上面提到的代码,如果你去掉大小的框,两个文本之间没有空格,你可以看到,你的 UI 和我的第一个 UI 一样,如果你评论 MainAxisAlignment.spaceBetween,没有区别
  • 你想要两个文本之间的空格,对吗?那有什么问题