【问题标题】:The equivalent of wrap_content and match_parent in flutter?相当于flutter中的wrap_content和match_parent?
【发布时间】:2017-07-04 14:28:35
【问题描述】:

在 Android 中,match_parentwrap_content 用于将小部件相对于其父级的大小自动调整为小部件包含的内容。

在 Flutter 中,默认情况下似乎所有小部件都设置为 wrap_content,我将如何更改它以便我可以将其 widthheight 填充为其父级?

【问题讨论】:

    标签: flutter dart flutter-widget


    【解决方案1】:

    您可以使用小技巧: 假设您有以下要求: (宽度,高度)

    包装内容,包装内容:

     //use this as child
     Wrap(
      children: <Widget>[*your_child*])
    

    Match_parent,Match_parent:

     //use this as child
    Container(
            height: double.infinity,
        width: double.infinity,child:*your_child*)
    

    Match_parent,Wrap_content :

     //use this as child
    Row(
      mainAxisSize: MainAxisSize.max,
      children: <Widget>[*your_child*],
    );
    

    Wrap_content ,Match_parent:

     //use this as child
    Column(
      mainAxisSize: MainAxisSize.max,
      children: <Widget>[your_child],
    );
    

    【讨论】:

    • 为了匹配父母,你也可以用 SizedBox.expand() 包装你的小部件
    【解决方案2】:

    为了获得 match_parentwrap_content 的行为,我们需要 在 Row/Column 小部件中使用 ma​​inAxisSize 属性,ma​​inAxisSize 属性采用 MainAxisSize 枚举具有两个值,即 MainAxisSize.min,其行为类似于 wrap_contentMainAxisSize.max 其行为类似于 match_parent

    原文章的Link

    【讨论】:

    • 我要补充一点,行和列上还有 crossAxisAlignment 字段,可以设置为 CrossAxisAlignment.stretch 以在列内水平扩展
    • 非常感谢!去年投了赞成票,然后很久没用flutter,几乎什么都忘记了,今天又帮我了。
    • 很好的答案!如果有人正在寻找更多此类示例,请使用以下链接 medium.com/flutter-community/…
    【解决方案3】:

    简短的回答是,在孩子有尺寸之前,父母没有尺寸。

    Flutter 中布局的工作方式是每个小部件为其每个子级提供约束,例如“你可以达到这个宽度,你必须有这个高度,你必须至少有这个宽度”,或者其他任何(具体来说,它们得到最小宽度、最大宽度、最小高度和最大高度)。每个孩子接受这些约束,做某事,并选择与这些约束匹配的大小(宽度和高度)。然后,一旦每个孩子都完成了自己的工作,小部件就可以选择自己的大小。

    一些小部件试图尽可能大到父级允许的大小。一些小部件试图尽可能小到父允许的大小。一些小部件尝试匹配某个“自然”大小(例如文本、图像)。

    一些小部件告诉他们的孩子他们可以是任何他们想要的大小。有些人给孩子的约束与他们从父母那里得到的约束相同。

    【讨论】:

    • Ian,当我在 Column 中有一个 PageView,在当前的 Column 中有另一个 Column 时,我得到一个渲染错误,但我可以通过包装 @ 来修复它987654325@ 在ExpandedFlexible 内。问题是,这两个选项只会扩展他们的孩子。为什么没有相关的小部件来收缩适合,比如“包装内容”,来解决这种渲染问题?
    【解决方案4】:

    实际上有一些可用的选项:

    您可以使用 SizedBox.expand 使您的小部件与父尺寸匹配,或使用 SizedBox(width: double.infinity) 仅匹配宽度或使用 SizedBox(heigth: double.infinity) 仅匹配高度。

    如果您想要一个 wrap_content 行为,它取决于您正在使用的父小部件,例如,如果您将一个按钮放在列上,它的行为将类似于 wrap_content 并且要像 match_parent 一样使用它,您可以使用 Expanded 小部件包装按钮或一个大小的盒子。

    使用 ListView,按钮会获得 match_parent 行为,而要获得 wrap_content 行为,您可以使用像 Row 这样的 Flex 小部件来包装它。

    使用 Expanded 小部件可创建 Row、Column 或 Flex 的子级 展开以填充主轴中的可用空间(例如,水平 行或垂直列)。 https://docs.flutter.io/flutter/widgets/Expanded-class.html

    使用 Flexible 小部件可以让 Row、Column 或 Flex 的子级灵活地展开以填充主轴上的可用空间(例如,水平地用于行或垂直地用于列),但与展开不同的是,灵活不需要孩子填充可用空间。 https://docs.flutter.io/flutter/widgets/Flexible-class.html

    【讨论】:

      【解决方案5】:

      使用小部件 Wrap

      对于 Column 类似的行为尝试:

        return Wrap(
                direction: Axis.vertical,
                spacing: 10,
                children: <Widget>[...],);
      

      对于Row之类的行为试试:

        return Wrap(
                direction: Axis.horizontal,
                spacing: 10,
                children: <Widget>[...],);
      

      欲了解更多信息:Wrap (Flutter Widget)

      【讨论】:

        【解决方案6】:

        我使用了这个解决方案,您必须使用 MediaQuery 定义屏幕的高度和宽度:

         Container(
                height: MediaQuery.of(context).size.height,
                width: MediaQuery.of(context).size.width
          )
        

        【讨论】:

          【解决方案7】:

          一个简单的解决方法:

          如果一个容器只有一个顶级子级,那么您可以为该子级指定对齐属性并为其赋予任何可用值。它会填满容器中的所有空间。

          Container(color:Colors.white,height:200.0,width:200.0,
           child:Container(
              color: Colors.yellow,
              alignment:Alignment.[any_available_option] // make the yellow child match the parent size
             )
          )
          

          另一种方式:

          Container(color:Colors.white,height:200.0,width:200.0,
           child:Container(
              color: Colors.yellow,
              constraints:  BoxConstraints.expand(height: 100.0), // height will be 100 dip and width will be match parent
             )
          )
          

          【讨论】:

          • BoxConstraints.expand(height: 100.0) 与 Android 的 width="match_parent" 等效
          【解决方案8】:
          Stack(
            children: [
              Container(color:Colors.red, height:200.0, width:200.0),
              Positioned.fill(
                child: Container(color: Colors. yellow),
              )
            ]
          ),
          

          【讨论】:

          • 虽然您的代码可能会回答这个问题,但一个好的答案应该始终解释代码的作用以及它如何解决问题。
          • 这不是包装内容的答案。这只是硬编码的宽度和高度。
          【解决方案9】:

          要让子元素填充其父元素,只需将其包装到 FittedBox 中

              FittedBox(
               child: Image.asset('foo.png'),
               fit: BoxFit.fill,
             )
          

          【讨论】:

            【解决方案10】:

            使用FractionallySizedBox 小部件。

            FractionallySizedBox(
              widthFactor: 1.0, // width w.r.t to parent
              heightFactor: 1.0,  // height w.r.t to parent
              child: *Your Child Here*
            }
            

            当您想将孩子的大小调整为父母大小的一小部分时,此小部件也非常有用。

            例子:

            如果您希望子级占据其父级的 50% 宽度,请将 widthFactor 提供为 0.5

            【讨论】:

              【解决方案11】:

              匹配父级

              要匹配或填充父级(高度和宽度),我们可以在 Container 上使用额外的 constraints

              Container(
                constraints: BoxConstraints.expand(), // ← this guy
                child: Text('Center > Container > Text')
              )
              

              在 Flutter 中,constraints 是您可以填充的空间(如果“严格”约束,则必须填充)。

              约束是给定的...实际上不是,强加是父母。

              默认情况下,Container 将包装其内容 (child:) 并根据其子级调整自身大小,除非被覆盖(或严格约束不允许)。

              使用constraints: 参数,我们可以提供Container 附加 约束来覆盖默认的Container 约束行为(例如包装内容)。

              使用Container(constraints: BoxConstraints.something) 不会覆盖传入/父约束;它只允许我们在允许的情况下覆盖默认行为,例如包装内容。


              代码示例 - BoxConstraints

              这是一个复制/粘贴代码示例,显示了各种constraints 的效果,我们可以将其应用于具有“松散”传入/父母约束的Container(由Center 提供)。

              import 'package:flutter/material.dart';
              
              class MatchParentPage extends StatefulWidget {
                @override
                _MatchParentPageState createState() => _MatchParentPageState();
              }
              
              class _MatchParentPageState extends State<MatchParentPage> {
                BoxConstraints constraints;
              
                @override
                Widget build(BuildContext context) {
                  return Scaffold(
                    appBar: AppBar(
                      title: Text('Match Parent'),
                    ),
                    body: Column(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        Expanded( // shares space constraint evenly with other Expanded
                          child: Center( // ← fills tight parent constraint & loosens ↓ child constraint ↓
                            child: Container( // got loose constraint from Center... 
                                constraints: constraints, // can apply many additional constraints
                                color: Colors.lightBlueAccent.withOpacity(.3),
                                child: Text('Center > Container > Text')),
                          ),
                        ),
                        Expanded(
                          child: Container(
                            color: Colors.orangeAccent,
                              child: Wrap(
                                  children: [
                                    _button('default', null),
                                    _button('*expand()', BoxConstraints.expand()),
                                    _button('*tight(Size.infinite)', BoxConstraints.tight(Size.infinite)),
                                    _button('tight(Size.zero)', BoxConstraints.tight(Size.zero)),
                                    _button('tight(Size.fromHeight(100))', BoxConstraints.tight(Size.fromHeight(100))),
                                    _button('tight(Size.fromWidth(100))', BoxConstraints.tight(Size.fromWidth(100))),
                                    _button('tightForFinite(width: 100, height: 100)', BoxConstraints.tightForFinite(width: 100, height: 100)),
                                    _button('loose(Size.infinite)', BoxConstraints.loose(Size.infinite)),
                                    _button('tightFor(width: double.infinity)', BoxConstraints.tightFor(width: double.infinity)),
                                    _button('tightFor(height: double.infinity)', BoxConstraints.tightFor(height: double.infinity)),
                                  ])
                          ),
                        )
                      ],
                    ),
                  );
                }
              
                Widget _button(String label, BoxConstraints _constraints) {
                  bool _active = _constraints == constraints;
                  return Padding(
                    padding: const EdgeInsets.only(top:8, left: 8),
                    child: RaisedButton(
                      color: _active ? Colors.cyanAccent : null,
                      child: Text(label),
                      onPressed: () {
                        setState(() => constraints = _constraints);
                      },
                    ),
                  );
                }
              }
              

              【讨论】:

                【解决方案12】:

                在 Column 中使用这行代码。 对于 wrap_content :mainAxisSize: MainAxisSize.min 对于 match_parent:mainAxisSize: MainAxisSize.max

                【讨论】:

                  猜你喜欢
                  • 2017-02-17
                  • 2015-04-02
                  • 1970-01-01
                  • 2017-11-27
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-06-03
                  相关资源
                  最近更新 更多