相当于 wrap_content 和 match_parent 在 flutter 中的作用?

The equivalent of wrap_content and match_parent in flutter?

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

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

简短的回答是 parent 没有尺寸,直到 child 有尺寸。

布局在 Flutter 中的工作方式是每个小部件为其每个 children 提供约束,例如 "you can be up to this wide, you must be this tall, you have to be at least this wide" 或其他任何内容(具体来说,它们具有最小宽度、最大宽度、最小高度和最大高度)。每个 child 接受这些约束,做一些事情,然后选择与这些约束相匹配的大小(宽度和高度)。然后,一旦每个 child 都完成了它的工作,小部件就可以选择自己的大小。

一些小部件试图尽可能大 parent 允许。一些小部件试图尽可能小 parent 允许。一些小部件尝试匹配特定的 "natural" 大小(例如文本、图像)。

一些小部件告诉他们 children 他们可以是他们想要的任何大小。有些人给他们的 children 和他们 parent.

一样的限制

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

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

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

使用 ListView,按钮会获得 match_parent 行为,要获得 wrap_content 行为,您可以使用 Row 等 Flex 小部件将其包装起来。

使用 Expanded 小部件可以 child 行、列或 Flex 扩展以填充主轴中可用的 space(例如,水平 行或垂直列)。 https://docs.flutter.io/flutter/widgets/Expanded-class.html

使用灵活的小部件使行、列或 Flex 的 child 可以灵活扩展以填充主轴中可用的 space(例如,行的水平或垂直对于列),但是与扩展不同,灵活不需要 child 来填充可用的 space。 https://docs.flutter.io/flutter/widgets/Flexible-class.html

一个简单的解决方法:

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

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
   )
)

In order to get behavior for match_parent and wrap_content we need to use mainAxisSize property in Row/Column widget, the mainAxisSize property takes MainAxisSize enum having two values which is MainAxisSize.min which behaves as wrap_content and MainAxisSize.max which behaves as match_parent.

原文章

Link

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

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

Wrap_content ,Wrap_content :

 //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],
);
Stack(
  children: [
    Container(color:Colors.red, height:200.0, width:200.0),
    Positioned.fill(
      child: Container(color: Colors. yellow),
    )
  ]
),

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

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

使用小工具 Wrap

对于Column喜欢的行为尝试:

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

对于Row喜欢的行为尝试:

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

更多信息:Wrap (Flutter Widget)

使用 FractionallySizedBox 小部件。

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

当您想将 child 的尺寸缩小为 parent 尺寸的一小部分时,此小部件也非常有用。

Example:

If you want the child to occupy 50% width of its parent, provide widthFactor as 0.5

要让子项填充其父项,只需将其包装到 FittedBox 中即可

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

匹配Parent

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

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

在 Flutter 中,constraints 是您可以填充的 space(或者 必须 填充,如果“紧”约束)。

约束是给定的...实际上没有,强加 parents.

默认情况下,Container 将包装其内容 (child:) 并将其自身调整为 child,除非被覆盖(或严格限制不允许)。

使用 constraints: 参数,我们可以给 Container 额外的 约束来覆盖默认的 Container 约束行为(例如包装内容) .

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


代码示例 - BoxConstraints

这是一个 copy/paste 代码示例,显示了各种 constraints 的效果,我们可以将其应用于具有“松散” incoming/parent 约束的 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);
        },
      ),
    );
  }
}

MATCH_PARENT

FractionallySizedBox(
            widthFactor: 1.0, // width w.r.t to parent
            heightFactor: 1.0, // height w.r.t to parent

            child: ElevatedButton(
              onPressed: () {},
              child: Text("+"),
            ),
          )

Container(
            height: double.infinity,
            width: double.infinity,
          child: ElevatedButton(
            onPressed: () {},
            child: Text("+"),
          ),
        )

Container(
            height: MediaQuery.of(context).size.height,
            width: MediaQuery.of(context).size.width,
          child: ElevatedButton(
            onPressed: () {},
            child: Text("+"),
          ),
        )

Container(
          constraints: BoxConstraints.expand(),
          child: ElevatedButton(
            onPressed: () {},
            child: Text("+"),
          ),
        )

WRAP_CONTENT

Wrap(children: [
          Container(
            child: ElevatedButton(
              onPressed: () {},
              child: Text("+"),
            ),
          ),
        ])

Container(
          constraints: BoxConstraints.tightFor(),
          child: ElevatedButton(
            onPressed: () {},
            child: Text("+"),
          ),
        )

Match_parent,Wrap_content :

Row(
            children: [
          Expanded(
            child: Container(
              child: ElevatedButton(
                onPressed: () {},
                child: Text("+"),
              ),
            ),
          ),
        ])

Wrap_content,Match_parent :

Column(
            children: [
          Expanded(
            child: Container(
              child: ElevatedButton(
                onPressed: () {},
                child: Text("+"),
              ),
            ),
          ),
        ])