在flutter中等同于wrap_content和match_parent ?

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

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

259072 次浏览

简单的回答是,在子节点有尺寸之前,父节点没有尺寸。

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

有些小部件试图尽量大,只要父组件允许。有些小部件试图尽量小,就像父组件所允许的那样。有些小部件试图匹配某种“自然”大小(例如文本、图像)。

一些小部件告诉它们的子部件可以是任意大小。有些人给他们的孩子同样的限制,他们从他们的父母。

实际上有一些选择:

你可以使用sizebox。扩展以使您的小部件匹配父维度,或者只匹配宽度的sizebox (width: double.infinity),或者只匹配高度的sizebox (height: double.infinity)。

如果你想要一个wrap_content行为,这取决于你正在使用的父部件,例如,如果你把一个按钮放在一个列上,它会像wrap_content一样行为,而像match_parent一样使用它,你可以用一个扩展的小部件或一个大小框来包装按钮。

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

使用展开的小部件使行、列或Flex成为子部件 展开以填充主轴上的可用空间(例如,水平地填充 行或垂直列)。 https://docs.flutter.io/flutter/widgets/Expanded-class.html < / p > 使用Flexible小部件为行、列或Flex的子部件提供了扩展以填充主轴上可用空间的灵活性(例如,水平地填充行或垂直地填充列),但与Expanded不同的是,Flexible不要求子部件填充可用空间。 https://docs.flutter.io/flutter/widgets/Flexible-class.html < / p >

一个简单的解决方法:

如果容器只有一个顶级子容器,则可以为该子容器指定对齐属性并为其赋值。它会填满容器里的所有空间。

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
)
)
为了获得match_parentwrap_content的行为,我们需要 在行/列小部件中使用mainAxisSize属性时,mainAxisSize . properties将使用 属性取MainAxisSize枚举,有两个值,即 MainAxisSize。mainaxisize .max . min,表现为wrap_content match_parent.

enter image description here

链接的原文章

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

你可以用小伎俩: 假设你有以下要求: (Width,Height)

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*
}

当您希望将子节点的大小调整为其父节点大小的一小部分时,这个小部件也非常有用。

例子:

如果你想让子对象占据父对象的50%宽度,提供widthFactor作为0.5

要让一个子填充它的父,只需将它包装到FittedBox中

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

匹配父

匹配或填充父元素(height &width),我们可以在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

下面是一个复制/粘贴代码示例,展示了可以应用于Container的各种constraints的效果,该Container具有"loose"传入/父约束(由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

enter image description here

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

enter image description here

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

Container(
constraints: BoxConstraints.tightFor(),
child: ElevatedButton(
onPressed: () {},
child: Text("+"),
),
)
< p > Match_parent, Wrap_content: enter image description here < / p >
Row(
children: [
Expanded(
child: Container(
child: ElevatedButton(
onPressed: () {},
child: Text("+"),
),
),
),
])
< p > Wrap_content, Match_parent: enter image description here < / p >
Column(
children: [
Expanded(
child: Container(
child: ElevatedButton(
onPressed: () {},
child: Text("+"),
),
),
),
])

对于匹配父选项,你可以用容器包装小部件,并给它一个这样的宽度

width: double.infinity

这种方法将使小部件填充屏幕上的最大可用空间。