【问题标题】: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(),
    ),
  ],
);

截图:

【问题讨论】:

    标签: flutter dart


    【解决方案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),
          ],
      );
      

      【讨论】: