Flutter 布局
今天我们来讲一下 Flutter 的基础布局,如果你之前是web前端开发转学 FLutter 的话,相信我, 这篇文章对你会有所帮助的(我自己刚学flutter的时候就因为带着web开发的思想踩了不少坑, 害,说多了都是泪). 话不多说, 咱们先来一个小例子热热身
void main(){
runApp(myApp())
}
Scaffold myApp(){
return Scaffold(
appBar: AppBar(
title: Text("Flutter Demo Home Page"),
),
body: const FlutterLogo(size: 40),
floatingActionButton: FloatingActionButton(
onPressed: (){},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
)
}
我们在 body 添加了一个 FlutterLogo, 这个组件有个 size 属性可以用来控制它的大小,具体的效果如下图:
现在 Logo 有了, 我想给它加一个背景色,提高整体的美感, 该怎么做呢?
具体代码如下:
Scaffold myApp(){
return Scaffold(
appBar: AppBar(
title: Text("Flutter Demo Home Page"),
),
body: Container(
color: Colors.green,
child: const FlutterLogo(size: 40),
),
floatingActionButton: FloatingActionButton(
onPressed: (){},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
完美,想要的效果出来了, 但总感觉不够劲儿, 这个绿色看起来没有那种自由的感觉, 我还得把这片绿色儿再给放大点, 怎么做呢?
具体代码如下:
Scaffold myApp(){
return Scaffold(
appBar: AppBar(
title: Text("Flutter Demo Home Page"),
),
body: Container(
height: 200,
width: 200,
color: Colors.green,
child: const FlutterLogo(size: 40),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
完美实现了那种充满自由气息的绿色背景, 这会儿可能有细心的读者就发现问题了:
- 上面代码我只给Container 指定了宽高,并未给FLutterLogo做任何调整,但是为啥 FlutterLogo 也相对应的增大了啊? (这肯定是 Flutter 的 Bug, 先拿个小本本记下来)
上面那个也不算是个大问题, 忍忍也就过去了. 我们继续添加新需求, 这回我想把这个白色的背景换成个黑色的,直接上代码看结果!
Scaffold myApp(){
return Scaffold(
appBar: AppBar(
title: Text("Flutter Demo Home Page"),
),
body: Container(
color: Colors.black,
child: Container(
height: 200,
width: 200,
color: Colors.green,
child: const FlutterLogo(size: 40),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
为什么背景颜色还是没有变啊? 这是什么情况?
肯定是我因为我没有给最外层的 Cotnainer 指定宽高, 所以它就按照它的child 的大小来填充了! 这次肯定没跑了, Flutter 不过如此跟 web 开发没啥区别嘛,这就修改代码
Scaffold myApp(){
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.black,
height: 400,
width: 400,
child: Container(
color: Colors.green,
width: 200,
height: 200,
child: const FlutterLogo(size: 40),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
为什么? 为什么绿色的 Container 变大了, FlutterLogo 怎么又变大了 ! 谁能告诉我这是为什 么! 我明明给子级的Container 设置了宽度和高度了啊, 为什么会不起作用呢 ?
Flutter 文档: 害, 但凡你稍稍看我一眼, 也不至于现在这样子啊.
相信对以上这些问题感到比较迷惑的读者, 应该是对 Flutter 的布局约束没有深入的了解,我们先抛抛开当前这个例子不谈, 先说一下这个布局约束, 布局约束是一个很常见的概念, 像是Ios的app 一般都是满足操作系统的布局约束的, 占满运行设备的整个屏幕
我们回过头来看下Flutter
void main(){
runApp(myApp())
}
runApp() 这个函数就是把当前的任意一个 widget 作为整个程序的 root(根),比如说:
void main() {
runApp(Container(
color: Colors.pink[200],
));
}
整个屏幕全变成粉红色了, 这个就是操作系统对我们每个app的一个约束, 每个app的root(根) widget 都要遵循这个约束, 这个root(根) Container 就算我手动设置它的大小, 他也是不会有丝毫改变的, 示例如下
void main() {
runApp(Container(
width: 400,
height: 400,
color: Colors.pink[200],
));
}
既然root Container 大小不能改变的话, 我们再给它插入一个child Container, 并且设置宽高, 背景色设置为白色, 看看是啥效果:
void main() {
runApp(Container(
width: 400,
height: 400,
color: Colors.pink[200],
child: Container(
color: Colors.white,
width: 200,
height: 200,
),
));
}
整个页面全部变白了,root Container 不生效情有可原, 毕竟它要满足操作系统的布局约束, 但是按理说child Container 理论上来讲应该是可以不沾满屏幕, 但是为什么却占满了呢?
这是因为我们没有告诉 root Container 当 child Container 在比较小的情况下, 应该摆放在哪里, 这个时候我们给 child Container 再添加一个 Center widget (Center 能让子级widget居中摆放) 试试看
void main() {
runApp(Container(
width: 400,
height: 400,
color: Colors.pink[200],
child: Center(
child: Container(
color: Colors.white,
width: 200,
height: 200,
),
),
));
}
__嗯!, 这个效果完美, 就是我们想要的 200 大小的一个Container, 这个时候我们再给 child Container 添加个 Flutter Logo 看看会发生什么样的现象
void main() {
runApp(Container(
width: 400,
height: 400,
color: Colors.pink[200],
child: Center(
child: Container(
color: Colors.white,
width: 200,
height: 200,
child: const FlutterLogo(size: 50),
),
),
));
}
FlutterLogo 会和 child Container 一样大, 原因也是因为 我们没有告诉 Flutter parent widget 当FlutterLogo 在较小尺寸时如何摆放的原因, 这里我们同样的在添加一个 Center 就完美解决了 FlutterLogo 尺寸 跟随 父级尺寸的问题
接下来让我们画张图, 来更加详细的了解一下布局约束
看完这个图之后是不是茅塞顿开 ? 哈哈哈, 又可以愉快的开发Flutter了, 今天的分享就先到这里