很多的布局中会有一个 constraints
属性,用于对控件做一个另外的约束,先看一下源码:
const BoxConstraints({
this.minWidth = 0.0,
this.maxWidth = double.infinity,
this.minHeight = 0.0,
this.maxHeight = double.infinity,
});
其属性的含义就不说了,最大/最小宽/高,最大为 double.infinity
,类似于 Android 的 match_content
;最小值为 0,看一下效果:
假如我们有一个
Container
布局,并且指定了它的宽高均为 200:body: Container( width: 200, height: 200, alignment: Alignment.center, child: Text( "哈哈哈", style: TextStyle(backgroundColor: Colors.lightGreenAccent), ), ),
它的显示效果如下:
我们给它加上一个
constraints
属性来看一下效果:constraints: BoxConstraints( minWidth: 100, ),
设置另外的约束,最小宽度为 100,你会发现还是原来那样,并没有变化,图就不上了,其原因就不必说了,你最小 100,我这本来就 200,自然不会有啥效果了,那么把 minWidth 设置的值设置的比 width 大呢?
设置
minWidht > width
constraints: BoxConstraints( minWidth: 300, ),
会发现变宽了:
那么
maxWidth
是如何约束的呢?body: Container( width: 200, height: 200, alignment: Alignment.center, constraints: BoxConstraints( maxWidth: 300, ), child: Text( "哈哈哈", style: TextStyle(backgroundColor: Colors.lightGreenAccent), ), ),
会发现 maxWidth 并没有产生效果,布局还是 200*200 ,那这个 maxWidth 如何起作用呢?
那将 maxWidth 设置为小于 width:
body: Container( width: 200, height: 200, alignment: Alignment.center, constraints: BoxConstraints( maxWidth: 100, ), child: Text("哈哈哈"), ),
显示效果如下:
会发现宽度变成了 100,所以我们可以总结一下这个约束规则:
maxWidth
不能小于minWidth
- 如果只是设置了
maxWidth
或者minWidth
,空间的宽度是max(minWidth, width)
或者min(maxWidth, width)
,高度同理。 - 如果同时设置了 max 和 min:
maxWidth > width > minWidth
,则宽度为width
width > maxWidth > minWidth
,则宽度为maxWidth
maxWidth > minWidth > width
,则宽度为minWidth
多重限制
假如说有多个布局嵌套,有多个 constraints
属性,那该以哪个为准呢?
我们先声明一个长宽都是 100 的矩形:
Widget box = new Container( width: 200, height: 200, color: Colors.deepOrange, );
在声明两个嵌套的布局,然后让这个 box 作为子控件加入:
ConstrainedBox( constraints: BoxConstraints( minWidth: 100, ), child: ConstrainedBox( constraints: BoxConstraints( minWidth: 300, ), child: box, ), ),
给最外层的布局设置
minWidth = 100
,内层布局设置minWidth = 300
,效果如下:再将内外层 minWidth 的值互换一下:
ConstrainedBox( constraints: BoxConstraints( minWidth: 300, ), child: ConstrainedBox( constraints: BoxConstraints( minWidth: 100, ), child: box, ), ),
会发现效果还是一样,所以对于嵌套的布局约束来说,对于 minWidth 的取值去取最大值,再看 maxWidth:
先设置外层布局的 maxWidth 大于内层的 maxWidth:
ConstrainedBox( constraints: BoxConstraints( maxWidth: 300, ), child: ConstrainedBox( constraints: BoxConstraints( maxWidth: 100, ), child: box, ), ),
其显示效果为:
发现是按最小的取值的,
再将内外层的值还一下:
ConstrainedBox( constraints: BoxConstraints( maxWidth: 100, ), child: ConstrainedBox( constraints: BoxConstraints( maxWidth: 300, ), child: box, ), ),
运行之后发现,效果并没有改变,所以得出结论:对于 maxWidth,内外层约束取最小值。
至此,我们可以得到当布局嵌套多个约束时,max 和 min 的取值了,然后自然也可以根据最一开始的单层嵌套来确定布局大小了。
BoxConstraints 提供的实例函数
在上面的例子中,都是直接指定 maxWidth
minWidth
maxHeight
minHeight
,BoxConstraints 还提供了一些示例函数可供开发者直接使用:
BoxConstraints.tight
,看源码:BoxConstraints.tight(Size size) : minWidth = size.width, maxWidth = size.width, minHeight = size.height, maxHeight = size.height;
该方法将 BoxConstraints 中的
minWidth
和maxWidth
设置为同一个值,minHeight
和maxHeight
设置为同一个值。BoxConstraints.tightFor
,看源码:const BoxConstraints.tightFor({ double width, double height, }) : minWidth = width ?? 0.0, maxWidth = width ?? double.infinity, minHeight = height ?? 0.0, maxHeight = height ?? double.infinity;
该方法设定宽高约束默认最小限制为0,最大限制为无穷大。
BoxConstraints.tightForFinite
,看源码:const BoxConstraints.tightForFinite({ double width = double.infinity, double height = double.infinity, }) : minWidth = width != double.infinity ? width : 0.0, maxWidth = width != double.infinity ? width : double.infinity, minHeight = height != double.infinity ? height : 0.0, maxHeight = height != double.infinity ? height : double.infinity;
该方法根据指定的宽高设置, 参数可为空
BoxConstraints.loose
,看源码:BoxConstraints.loose(Size size) : minWidth = 0.0, maxWidth = size.width, minHeight = 0.0, maxHeight = size.height;
该方法只设置了最大的宽高值。
BoxConstraints.expand
,看源码:const BoxConstraints.expand({ double width, double height, }) : minWidth = width ?? double.infinity, maxWidth = width ?? double.infinity, minHeight = height ?? double.infinity, maxHeight = height ?? double.infinity;
该方法根据宽高设置, 如果参数为空则默认为最大值