- 本篇参考资料《Flutter实战》
- 本篇文章只是本人看书的理解和整理的笔记,更完整的内容还在书上!
- 电子书链接:https://book.flutterchina.club/
- Flutter中文社区链接:https://flutterchina.club/
- 尊重原作者,能支持购买实体书当然最好
一.线性布局Row和Column
提到线性布局,我们第一个需要掌握的概念就是主轴和纵轴
Row横向布局的主轴就是水平方向,纵轴就是垂直方向
Column垂直布局主轴就是垂直方向,纵轴就水平方向

mainAxisSize
是控制布局大小的属性,有MainAxisSize.min和max,min表示大小和内部控件大小之和相等,max表示填充完父控件。如果Row里面嵌套Row,或者Column里面再嵌套Column,那么只有最外面的Row或Column会占用尽可能大的空间,里面Row或Column所占用的空间为实际大小,使用Expanded可以灵活改变内部控件大小。
二.弹性布局
弹性布局通常是Expanded属性flex的使用,类似于Android中的View比重weight这个属性,可以使用与Flex,Row和Column三个布局中。
Flex是Row和Column的父类,它有一个属性direction可以设置子控件排列方向
弹性布局用法如下:
//Flex的两个子widget按1:2来占据水平空间
Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
height: 30.0,
color: Colors.red,
),
),
Expanded(
flex: 2,
child: Container(
height: 30.0,
color: Colors.green,
),
),
],
)
三.流式布局
流式布局有两个Wrap和Flow,我们通常使用Wrap。
Wrap能在子控件在主轴超出范围时,自动折行,除此之外其他的属性和Flex都一样。
Wrap主轴水平的时候,高度允许的情况下进行折行
Wrap主轴竖直的时候,宽度允许的情况下进行折列

Wrap(
direction: Axis.horizontal,
spacing: 5.0,
//主轴间距
runSpacing: 1,
//纵轴间距
alignment: WrapAlignment.center,
//沿主轴方向居中
children: <Widget>[
new Chip(
avatar: new CircleAvatar(
backgroundColor: Colors.blue, child: Text('A')),
label: new Text('Hamilton'),
),
new Chip(
avatar: new CircleAvatar(
backgroundColor: Colors.blue, child: Text('M')),
label: new Text('Lafayette'),
),
new Chip(
avatar: new CircleAvatar(
backgroundColor: Colors.blue, child: Text('H')),
label: new Text('Mulligan'),
),
new Chip(
avatar: new CircleAvatar(
backgroundColor: Colors.blue, child: Text('J')),
label: new Text('Laurens'),
),
]),
Container(
height: 200,
width: 200,
color: Colors.grey[200],
child: Wrap(
direction: Axis.vertical,
spacing: 5,
//主轴间距
runSpacing: 5,
children: <Widget>[
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],),
Container(height: 50, width: 20, color: Colors.pink[100],)
],
),
),
三.叠层布局
叠层布局有点像Android的RelativeLayout相对布局,可以设置子元素相对于Stack四边的距离来控制位置和大小,Stack通常是配合Positioned一起使用,比如左上角距离左边20,顶部20的粉色方块:
Stack(
alignment: Alignment.center, //指定未定位或部分定位widget的对齐方式
fit: StackFit.loose, //指定未确定大小的子组件默认大小
children: <Widget>[
Positioned(
left: 10,
top: 10,
child: Container(
height: 20,
width: 20,
color: Colors.pink[200],
)
),
)
Positioned有如下8个属性:
const Positioned({
Key key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
@required Widget child,
})
left、top 、right、 bottom分别代表离Stack左、上、右、底四边的距离。width和height用于指定需要定位元素的宽度和高度。注意,Positioned的width、height 和其它地方的意义稍微有点区别,此处用于配合left、top 、right、 bottom来定位组件,举个例子,在水平方向时,你只能指定left、right、width三个属性中的两个,如指定left和width后,right会自动算出(left+width),如果同时指定三个属性则会报错,垂直方向同理。
也就是说我同时指定距离左边和右边的距离后,子空间的宽度会被自动算出来,这时候在子控件内的宽度失效。
在实际开发布局中,尽量使用相对的方式来确定组件的位置和大小,以适应不同的手机屏幕
网友评论