如果需要,允许扩展小部件占用更多空间

Posted

技术标签:

【中文标题】如果需要,允许扩展小部件占用更多空间【英文标题】:Allow Expanded Widget to take more space if needed 【发布时间】:2021-10-28 19:20:06 【问题描述】:

我希望Expanded 小部件具有最小宽度(在flex 中指定),但如果孩子需要它,它也应该增加它的宽度。 但是,它只将flex 解释为某种固定宽度。

您可以在以下屏幕截图中看到它。

示例代码:


Row(
  children: [
    Expanded(
      flex: 117,
      child: Widget(),
    ),
    Expanded(
      flex: 400,
      child: Widget(),
    ),
    Expanded(
      flex: 13,
      child: Widget(),
    ),
    Expanded(
      flex: 470,
      child: Widget(),
    ),
  ],
);

截图:

【问题讨论】:

【参考方案1】:

您可以使用 Container Widget 的约束属性。 -我认为-

你可以试试这个:

Row(
  children: [
    Expanded(
      flex: 117,
      child: Container(
         constraints: BoxConstraints(minWidth: 40),
         child: Widget(),
      ),
    ),
    Expanded(
      flex: 400,
      child: Container(
         constraints: BoxConstraints(minWidth: 40),
         child: Widget(),
      ),
    ),
    Expanded(
      flex: 13,
      child: Container(
         constraints: BoxConstraints(minWidth: 40),
         child: Widget(),
      ),
    ),
    Expanded(
      flex: 470,
      child: Container(
         constraints: BoxConstraints(minWidth: 40),
         child: Widget(),
      ),
    ),
  ],
);

编辑 1:我创建了名为 MinHeightExpanded 的自定义小部件。

MinHeightExpanded 小部件:

class MinHeightExpanded extends StatefulWidget 
  const MinHeightExpanded(
    Key? key,
    required this.minHeight,
    required this.flex,
    required this.color,
  ) : super(key: key);

  final double minHeight;
  final int flex;
  final Color color;

  @override
  _MinHeightExpandedState createState() => _MinHeightExpandedState();


class _MinHeightExpandedState extends State<MinHeightExpanded> 
  bool setToMin = false;

  @override
  Widget build(BuildContext context) 
    WidgetsBinding.instance!.addPostFrameCallback((timeStamp) => setState(() ));
    return !setToMin
        ? Expanded(
            flex: widget.flex,
            child: LayoutBuilder(
              builder: (BuildContext context, BoxConstraints boxConstraints) 
                print("$widget.color: $boxConstraints.maxHeight");
                if (boxConstraints.maxHeight < widget.minHeight) 
                  setToMin = true;
                
                return Container(
                  color: widget.color,
                );
              ,
            ),
          )
        : Container(
            color: widget.color,
            height: widget.minHeight,
          );
  

像这样使用它:

     SizedBox(
        height: size.height,
        width: double.infinity,
        child: Column(
          mainAxisSize: MainAxisSize.max,
          children: [
            MinHeightExpanded(
              flex: 117,
              color: Colors.red,
              minHeight: 40,
            ),
            MinHeightExpanded(
              flex: 400,
              color: Colors.yellow,
              minHeight: 40,
            ),
            MinHeightExpanded(
              flex: 13,
              color: Colors.blue,
              minHeight: 400,
            ),
            MinHeightExpanded(
              flex: 470,
              color: Colors.green,
              minHeight: 40,
            ),
          ],
        ),
      ),

【讨论】:

不幸的是,它不起作用。 Expanded 小部件似乎具有更高的优先级。 这个link可以给你一个提示。我暂时也没有找到办法。 我编辑了我的答案。您可能想检查一下。效果很好。 我将它编辑为我这边的 minWidth。谢谢,它工作得很好。【参考方案2】:

为什么不删除您想要增加宽度的孩子的Expanded。喜欢

Row(
  children: [
    Expanded(
      flex: 117,
      child: Widget(),
    ),
    Expanded(
      flex: 400,
      child: Widget(),
    ),
    Widget(),
    Expanded(
      flex: 470,
      child: Widget(),
    ),
  ],
);

如果不想设置百分比,可以使用IntrinsicWidth,点赞

    IntrinsicWidth(
        child: Row(children: [
      Widget(),
      Widget(),
      Widget(),
      Widget(),
    ]));

但是很贵

【讨论】:

嗯,我事先不知道百分比。它也可能是第一项。 @TienDoNam 我尝试另一个建议【参考方案3】:

如果我理解正确,这里是您问题的答案。

使用灵活小部件而不是扩展小部件。 Flutter: Expanded vs Flexible

【讨论】:

【参考方案4】:

@HazarBelge 的回答确实有效,但我找到了一个更优雅的解决方案:

组件:

class PercentageRow extends StatelessWidget 

  final List<double> percentages;
  final List<Widget> children;

  const PercentageRow(required this.percentages, required this.children);

  @override
  Widget build(BuildContext context) 
    return Table(
      columnWidths: percentages.map((p) => IntrinsicColumnWidth(flex: p)).toList().asMap(),
      children: [TableRow(children: children)],
    );
  

用法:

PercentageRow(
    percentages: [0.3, 0.7],
    children: [
      Container(color: Colors.red, child: Text('A LOOOOOONG TEXT')),
      Container(color: Colors.green),
    ],
);

【讨论】:

以上是关于如果需要,允许扩展小部件占用更多空间的主要内容,如果未能解决你的问题,请参考以下文章

占用太多空间的 Swiftui 小部件列表

多种小部件尺寸

隐藏 UIView 并调整其他小部件以占用空间?

Flutter - 如何让方形小部件连续占用其最大可能空间?

如何在 Kivy 中设置小部件/布局的最小允许宽度/高度?

防止小部件填充Flutter中扩展的祖先