列中扩展小部件的特定最小和最大尺寸

use*_*643 14 flutter flutter-layout

我有一个带有一组扩展小部件的列。

有没有办法控制它们扩展的范围?我希望一个小部件仅扩展到特定大小,并使其余小部件可用于其他小部件。

编辑:

因为我得到了两个可能具有误导性的答案,所以我想澄清一下。我想要这样的东西:

Expanded(flex: 1, minSize: 50, maxSize: 200, child: ...)
Run Code Online (Sandbox Code Playgroud)

这意味着这个展开的小部件的 flex 为 1,但不应小于 50 和大于 200。

yel*_*ray 18

简而言之:如果不计算尺寸,就没有简单的答案。

首先你需要知道:控制Row/ColumnWidget with Size中的可用大小,然后Flexiable/Expanded共享剩余空间。

Column(
  children:[
    Flexiable(...
    Expanded(...
    SizedBox(...  // <- dominate the avialable size first
  ]
)
Run Code Online (Sandbox Code Playgroud)

并且父窗口小部件支配子窗口小部件的大小:

Column(
  children:[
    Flexiable(flex: 1),
    Flexiable(
      flex: 1,
      child: SizedBox(...  // size can't be larger than 1/2
  ]
)
Run Code Online (Sandbox Code Playgroud)

尺寸超出或不足就是选择问题。我可以在下面展示一些简单的例子:

(顺便说一句:我用SizedBox替换ConstraintedBox因为我们只使用。检查Understanding ConstraintsmaxWidth/maxHeight

具有最大尺寸的 Flex

本例很简单,只能使用Flexible + SizedBox

Row(
  children: [
  Flexible(flex: 1, child: _textWidget('Flex:1')),
  Flexible(
    flex: 1,
    child: SizedBox(
      width: 300,
      child: _textWidget('Flex: 1, max: 300'),
      ),
    ),
  ],
),
Run Code Online (Sandbox Code Playgroud)

具有最小/最大尺寸的 Flex

对于这种情况,需要总大小(来自LayoutBuilder)和小部件大小的百分比。

LayoutBuilder(
  builder: (context, constraint) {
    final maxWidth = constraint.maxWidth;
    
    return Row(
      children: [
        Flexible(flex: 1, child: _textWidget('Flex:1')),
        SizedBox(
          width: (maxWidth / 3).clamp(200, 300),
          child: _textWidget('Flex:1, min: 200, max: 300'),
        ),
        SizedBox(
          width: (maxWidth / 3).clamp(200, 300),
          child: _textWidget('Flex:1, min: 200, max: 300'),
        ),
      ],
    );
  }
)
Run Code Online (Sandbox Code Playgroud)

代码示例

https://dartpad.dev/?id=f098f9764acda1bcc58017aa0bc0ec09

在此输入图像描述


Ben*_*Lee 9

据我所知,Flutter 中没有优雅的预构建方法可以做到这一点。

@HugoPassos 的答案仅部分完整。ConstrainedBox 不会改变其大小,除非其内容改变大小。我相信您正在寻找的是,如果行的 1/4 大于最小值并高于最大值,则该框为行宽度的 1 / 4。

这是一个工作 main.dart,它可以使用行中的宽度完成工作,尽管您也可以轻松地使用列中的高度:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String title;
  MyHomePage({required this.title});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: LayoutBuilder(builder: (context, constraints) {
          return Center(
              child: Row(
            children: [
              ConstrainedWidthFlexible(
                minWidth: 50,
                maxWidth: 200,
                flex: 1,
                flexSum: 4,
                outerConstraints: constraints,
                child: SizeLogger(
                  child: Container(
                      color: Colors.red,
                      width: Size.infinite.width,
                      height: Size.infinite.height,
                      child: Text('click me to log my width')),
                ),
              ),
              Flexible(
                flex: 1,
                fit: FlexFit.tight,
                child: Container(color: Colors.green),
              ),
              Flexible(
                flex: 2,
                fit: FlexFit.tight,
                child: Container(color: Colors.blue),
              ),
            ],
          ));
        }));
  }
}

class SizeLogger extends StatelessWidget {
  final Widget child;
  SizeLogger({required this.child});
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTap: () => {print('context.size!.width ${context.size!.width}')},
        child: child);
  }
}

class ConstrainedWidthFlexible extends StatelessWidget {
  final double minWidth;
  final double maxWidth;
  final int flex;
  final int flexSum;
  final Widget child;
  final BoxConstraints outerConstraints;
  ConstrainedWidthFlexible(
      {required this.minWidth,
      required this.maxWidth,
      required this.flex,
      required this.flexSum,
      required this.outerConstraints,
      required this.child});
  @override
  Widget build(BuildContext context) {
    return ConstrainedBox(
      constraints: BoxConstraints(
        minWidth: minWidth,
        maxWidth: maxWidth,
      ),
      child: Container(
        width: _getWidth(outerConstraints.maxWidth),
        child: child,
      ),
    );

  }

  double _getWidth(double outerContainerWidth) {
    return outerContainerWidth * flex / flexSum;
  }
}


Run Code Online (Sandbox Code Playgroud)


小智 8

在 Rows 中使用 ConstrainedBox 时,我的 minWidth 被忽略,而 maxWidth 被用作固定大小。


Hug*_*sos 7

您正在寻找ConstrainedBox.

您可以同时使用and创建 a Listof Widgets ,如下所示:ConstrainedBoxExpanded

Row(
  children: [
    ConstrainedBox(
      child: Container(color: Colors.red),
      constraints: BoxConstraints(
        minWidth: 50,
        maxWidth: 100,
      ),
    ),
    Expanded(
      child: Container(color: Colors.green),
    ),
    Expanded(
      child: Container(color: Colors.blue),
    ),
  ],
),
Run Code Online (Sandbox Code Playgroud)

  • 在此示例中,未使用 minWidth。红色容器的宽度始终为 100。 (4认同)