Flutter布局通常会呈现一些奇怪的现象,例如,我期望一个Container是100宽高的正方形,于是我这样写
void main() => runApp(Home());
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.amber,
width: 100,
height: 100,
);
}
}
可是成果却是全屏. 感觉难以了解,呈现这种情况的原因是,Flutter布局方法是对Widget Tree先进行自上而下对每个Widget进行束缚(Constraint 过程),再自下而上决议每个Widget的巨细(Size 过程),最终由父Widget决议每个子Widget的方位.总结下来就三步
-
1,向下Constraint
-
2,向上Size
-
3,父Widget决议方位
这儿咱们来解释一下上面的代码为什么会白屏. 在第一步过程中屏幕是Container的父亲,屏幕给Container的束缚是和屏幕相同大,在向上Size的过程中,这儿咱们有必要了解的是,不是子Widget想多大就多大,它有必要考虑它的束缚后给出一个巨细,这儿虽然它是宽100,高100不过束缚强制它全屏了,所以向上Size的时分它便是全屏巨细,最终父亲也便是屏幕决议它的方位,也便是坐标(0,0).
咱们改一下代码
void main() => runApp(Home());
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.amber,
width: 100,
height: 100,
),
);
}
}
现在咱们对Container包裹了一个Center,运行后是
现在和咱们期望的姿态相同了,因为现在的Center关于它子Widget的束缚不是屏幕巨细了,而是子Widget它期望自己多大就多大,最终Center决议Container的方位是居中,这样就看到了运行后的作用了。
这儿可能会有个疑问是,为什么屏幕关于子Widget的束缚是全屏幕巨细,而Center关于它子Widget的束缚却是它期望多大就多大呢?我怎样知道一个父Widget的是怎样束缚子Widget的呢?
关于屏幕它是作为一个最上层的父亲,它给予第一个Widget(根Widget)的束缚便是屏幕巨细,不管根Widget怎样设置自己巨细都授全屏束缚。接下来Widget的束缚便是依据详细情况详细定了(视Widget类型,剩下空间等影响,详细情况详细剖析)
下面咱们再来一个比如
void main() => runApp(Home());
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Container(
color: Colors.amber,
width: 100,
height: 100,
),
);
}
}
运行后变成这样 又是全屏了,这儿证明了Container关于子Widget束缚是撑满的. 那么我不想撑满,除了之前说到的Center还有哪些方法呢? 1,运用Align Align能够用来对齐一个Widget,同时它对子Widget的巨细束缚是子widget想多大就多大.(当然这儿还需要满足Align父亲的束缚).
void main() => runApp(Home());
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.centerLeft,
child: Container(
color: Colors.amber,
width: 100,
height: 100,
),
);
}
}
2,运用Stack
void main() => runApp(Home());
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
textDirection: TextDirection.ltr,
children: [
Container(
color: Colors.amber,
width: 100,
height: 100,
)
],
);
}
}
当然还有其它Widget是对子Widget的巨细束缚是子widget想多大就多大,详细这儿就不一一列举了.
最终再来看一个Colum的比如,回忆下布局束缚的整个流程.
void main() => runApp(Home());
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
color: Colors.amber,
width: 100,
height: 100,
),
Container(
color: Colors.red,
width: 100,
height: 100,
),
Container(
color: Colors.blue,
width: 100,
height: 100,
),
],
);
}
}
咱们来剖析一遍
1,Column作为第一个Widget,自然是全屏.
2,在Column束缚下,三个Container需要100的宽高,Column都能满足它们的要求
3,依据Column的布局特性决议三个Container的方位.
结语:
Flutter中Widget不能决议它自己的巨细和方位,有必要要结合父Widget的束缚去决议,相同父Widget也有父Widget,所以咱们在指定Widget的方位和巨细的时分一定要把父Widget的束缚考虑进去.