大家好,我是 17。
如果你是 web 前端开发,你一定会这样的体会, wigth,height 都是作用于 element 本身
<div style='width:100px;height:100px; ></div> 复制代码
在页面中,这个 div 的高宽一定是 100 高 100 宽的。带着这样的认识,当你学习 flutter的时候,很容易会觉得 container 的 width ,height,也是这样的作用。但事实上,container 的 width ,height 只是约束,container 实际的尺寸是由约束,孩子的尺寸,和本身的规则一起决定的。
flutter 中的布局遵循这样的原则 constrains go down ,sizes go up. Parent sets position. 直译过来就是 constrains 向下传递,sizes 向上传递。parent 决定尺寸。
constrains class
因为 constrains 是抽象类,所以 看看 boxConstrains 的构造函数
const BoxConstraints({ this.minWidth = 0.0, this.maxWidth = double.infinity, this.minHeight = 0.0, this.maxHeight = double.infinity, }) 复制代码
一共有四个值。默认值的意思是 尺寸可以随意,没有限制。特别的,最大最小值相同的 contains 称为 tight constrains,最小值为0 的 contains 称为 loose contains。一般来说,只要最大最小不相同的都可以看成是 loose constrains。
下面我会举例子,不用 container ,因为它是一个复合 widget,比较复杂。因为是研究 contrasins,所以只用最简单的 widget。第一个例子会给出完整代码,后面的例子只给出关键代码。
我是用 chrome,renderView 调整为 500 x 296,具体多少不重要,你只要知道看到这个数值就是满屏就行了。
例一
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const DecoratedBox(decoration: BoxDecoration(color: Colors.green)); } } 复制代码
把上面的代码 copy 到 main.dart中,执行,会发现全屏都是绿色。其间发生了如下的沟通过程。
- app 告诉 DecoratedBox, 你的尺寸必须是 500 x 296
- DecoratedBox 显示为 500 x 296
app 是如何告诉 DecoratedBox 的呢,是传 constrains 给 DecoratedBox
constraints: BoxConstraints(w=500.0, h=296.0) 复制代码
例二
const Center(child: DecoratedBox(decoration: BoxDecoration(color: Colors.green))); 复制代码
当用 Center 包装后,什么都不会显示。这涉及到 DecoratedBox 自身的规则,它会尽量小。
- app 告诉 Center, 你的尺寸必须是 500 x 296
- Center 告诉 DecoratedBox 你可以显示为任意尺寸,只要别超过 500 x 296
- DecoratedBox 最小可以显示为 0 ,所以我们就看不见了。
Center 传给 DecoratedBox 的约束
constraints: BoxConstraints(0.0<=w<=500.0, 0.0<=h<=296.0) 复制代码
Center 继承 自 Align。 Align 的一个功能就是把 tight 约束 转为 loose 约束
例三
Center( child: ConstrainedBox( constraints: const BoxConstraints(minWidth: 100, minHeight: 100), child: const DecoratedBox( decoration: BoxDecoration(color: Colors.green)))); 复制代码
DecoratedBox 获得了最小尺寸约束,所以它只好显示为 100 x 100
每次都写全四个属性有点麻烦,所以 ConstrainedBox 给出了快捷构造函数,拿 tight举例,其它就不再赘述了。
BoxConstraints.tight(Size size)
Size只有两个参数,width,height
const Size(double width, double height) 复制代码
用 BoxConstraints.tight可以构造出 最大最小相等的约束。
BoxConstraints.tight(Size(width:100,height:100) 复制代码
等价于
BoxConstraints(minWidth: 100, minHeight: 100,maxHeight: 100,maxWidth: 100) 复制代码
例四
const Center( child: SizedBox( width: 100, height: 100, child: DecoratedBox( decoration: BoxDecoration(color: Colors.green)))); 复制代码
用 SizedBox 可以达到同样的效果,而且代码更简洁些。和 ConstrainedBox 相比,SizedBox 只能构造 tight 约束。
例五
const Center( child: SizedBox( width: 100, height: 100, child:SizedBox( width: 300, height:300, child: DecoratedBox( decoration: BoxDecoration(color: Colors.green)))) ); 复制代码
可能你会认为 box 会显示为 300 x 300,但实际上是 100 x 100,这是因为 SizedBox,ConstrainedBox 把综合父级和自身的 contains ,处理后传给子级。
因为父级传过来的是 tight 约束 SizedBox,ConstrainedBox 会忽略自身的约束。所以显示为 100 x100