Flutter第4天--基础控件(下)+Flex布局详解

0.前言

Flex布局是Flutter的五虎上将之一,虎父无犬子,其子Row和Column也能力非凡
你有没有被mainAxisAlignment,crossAxisAlignment弄得晕头转向,本文将助你将他们纳入麾下。
先看一下父子三人在Flutter布局体系中的位置:多子组件布局


1.Flex的属性一览
属性名 类型 默认值 简介
direction Axis @required 轴向
mainAxisAlignment MainAxisAlignment start 主轴方向对齐方式
crossAxisAlignment CrossAxisAlignment center 交叉轴方向对齐方式
mainAxisSize MainAxisSize max 主轴尺寸
textDirection TextDirection null 文本方向
verticalDirection VerticalDirection down 竖直方向
textBaseline TextBaseline null 基线类型
children List [] 内部孩子

2.轴向:direction:Axis
1
2
3
4
enum Axis {
horizontal,//水平
vertical,//竖直
}

也就是水平排放还是竖直排放,可以看出默认情况下都是主轴顶头,交叉轴居中
比如horizontal下主轴为水平轴,交叉轴则为竖直。也就是水平顶头,竖直居中
这里使用MultiShower快速展示,更好的对比出不同之处,MultiShower详见

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var direction =[Axis.horizontal,Axis.vertical];
var show = MultiShower(direction,(e){
return Flex(
direction: e,
children: <Widget>[redBox,blueBox,yellowBox,greenBox],

);
},color: Colors.black12,width: 300,height: 200);

var redBox= Container(
color: Colors.red,
height: 50,
width: 50,
);

var blueBox= Container(
color: Colors.blue,
height: 30,
width: 60,
);

var yellowBox= Container(
color: Colors.yellow,
height: 50,
width: 100,
);

var greenBox= Container(
color: Colors.green,
height: 60,
width: 60,
);

3.主轴方向:mainAxisAlignment:MainAxisAlignment

主轴方向的排布规则,这里以水平为例,主轴为水平方向。竖直类比即可

1
2
3
4
5
6
7
enum MainAxisAlignment {
start,//顶头
end,//接尾
center,//居中
spaceBetween,//顶头接尾,其他均分
spaceAround,//中间的孩子均分,两头的孩子空一半
spaceEvenly,//均匀平分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
testMainAxisAlignment(){
var redBox= Container(
color: Colors.red,
height: 50,
width: 50,
);

var blueBox= Container(
color: Colors.blue,
height: 30,
width: 60,
);

var yellowBox= Container(
color: Colors.yellow,
height: 10,
width: 10,
);

var greenBox= Container(
color: Colors.green,
height: 50,
width: 10,
);

var mainAxisAlignment =[
MainAxisAlignment.start,MainAxisAlignment.center,
MainAxisAlignment.end,MainAxisAlignment.spaceAround,
MainAxisAlignment.spaceBetween,MainAxisAlignment.spaceEvenly];

var show = MultiShower(mainAxisAlignment,(e){
return Flex(
direction: Axis.horizontal,
mainAxisAlignment: e,
children: <Widget>[redBox,blueBox,yellowBox,greenBox],

);
},color: Colors.black12,width: 200,height: 150);
return show;
}

4.交叉轴方向:crossAxisAlignment:CrossAxisAlignment
1
2
3
4
5
6
7
enum CrossAxisAlignment {
start,//顶头
end,//接尾
center,//居中
stretch,//伸展
baseline,//基线
}

还是水平为例,交叉轴便是竖轴,这里可以看出他们的布局行为
其中需要注意的是CrossAxisAlignment.baseline使用时必须有textBaseline
其中textBaseline确定对齐的是那种基线,分为alphabeticideographic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
testCrossAxisAlignment(){
var redBox= Container(
color: Colors.red,
height: 50,
width: 50,
);

var blueBox= Container(
color: Colors.blue,
height: 30,
width: 60,
);

var yellowBox= Container(
color: Colors.yellow,
height: 10,
width: 10,
);

var greenBox= Container(
color: Colors.green,
height: 50,
width: 10,
);

var crossAxisAlignment =[CrossAxisAlignment.start,CrossAxisAlignment.center,
CrossAxisAlignment.end,CrossAxisAlignment.stretch,CrossAxisAlignment.baseline];

var show = MultiShower(crossAxisAlignment,(e){
return Flex(
direction: Axis.horizontal,
crossAxisAlignment: e,
textBaseline: TextBaseline.alphabetic,//基线类型
children: <Widget>[redBox,blueBox,yellowBox,greenBox],

);
},color: Colors.black12,width: 200,height: 140);

return show;
}

5.主轴尺寸:mainAxisSize
1
2
3
4
enum MainAxisSize {
min,
max,
}

当父容器的宽未约束,Flex默认会将自身尽可能延伸,这便是MainAxisSize.max

此时改为MainAxisSize.min时,它不会延伸自己的区域,自会包裹内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
testMainAxisSize(){
var redBox= Container(
color: Colors.red,
height: 50,
width: 50,
);

var blueBox= Container(
color: Colors.blue,
height: 30,
width: 60,
);

var yellowBox= Container(
color: Colors.yellow,
height: 10,
width: 10,
);

var greenBox= Container(
color: Colors.green,
height: 50,
width: 10,
);

return Center(child: Flex(
direction: Axis.horizontal,
mainAxisSize: MainAxisSize.max,
children: <Widget>[redBox,blueBox,yellowBox,greenBox],

),);
}

6.文字方向:textDirection:TextDirection
1
2
3
4
enum TextDirection {
ltr,//从左到右
rtl,//从右到左
}

这个非常好理解,不多言了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
testTextDirection(){
var redBox= Container(
color: Colors.red,
height: 50,
width: 50,
);

var blueBox= Container(
color: Colors.blue,
height: 30,
width: 60,
);

var yellowBox= Container(
color: Colors.yellow,
height: 10,
width: 10,
);

var greenBox= Container(
color: Colors.green,
height: 50,
width: 10,
);

var textDirection =[TextDirection.ltr,TextDirection.rtl];
var show = MultiShower(textDirection,(e){
return Flex(
direction: Axis.horizontal,
textDirection: e,
children: <Widget>[redBox,blueBox,yellowBox,greenBox],

);
},color: Colors.black12,width: 200,height: 140);
return show;
}

7.竖直方向排序:verticalDirection:VerticalDirection
1
2
3
4
enum VerticalDirection{
up,
down,
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
testVerticalDirection(){
var redBox= Container(
color: Colors.red,
height: 50,
width: 50,
);

var blueBox= Container(
color: Colors.blue,
height: 30,
width: 60,
);

var yellowBox= Container(
color: Colors.yellow,
height: 10,
width: 10,
);

var greenBox= Container(
color: Colors.green,
height: 50,
width: 10,
);

var verticalDirection =[VerticalDirection.up,VerticalDirection.down];

var show = MultiShower(verticalDirection,(e){
return Flex(
direction: Axis.vertical,
verticalDirection: e
children: <Widget>[redBox,blueBox,yellowBox,greenBox],

);
},color: Colors.black12,width: 200,height: 140);

return show;
}

8.基线对齐方式:textBaseline:TextBaseline
1
2
3
4
enum TextBaseline {
alphabetic,
ideographic,
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
testTextBaseline(){
var redBox= Text(
"张风捷特烈",style: TextStyle(fontSize: 20,backgroundColor: Colors.red),
);

var blueBox= Text(
"toly",style: TextStyle(fontSize: 50,backgroundColor: Colors.blue),
);

var yellowBox= Text(
"1994",style: TextStyle(fontSize: 30,backgroundColor: Colors.green),
);

var textBaseline =[TextBaseline.alphabetic,TextBaseline.ideographic];

var show = MultiShower(textBaseline,(e){
return Flex(
direction: Axis.horizontal,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: e,
children: <Widget>[redBox,blueBox,yellowBox],
);
},color: Colors.black12,width: 300,height: 140);

return show;
}

至此,Flutter中的Flex布局就已经完全解读完了。
其中Flutter的孩子Row是direction: Axis.horizontal,Column是direction: Axis.vertical,
其他的属性都是类似的,相当于Flex的简化版,所以Flex在手,天下我有。


Expanded与Flex的搭配— [更新于2019.1.22]

还要一点是关于Expanded,也比较保用,它能与Flex布局结合,变更孩子尺寸

1
2
3
4
c1:绿色  c2:红色  c3:黄色
1).Expanded--c2c1c3将不变,c2延伸自己占满剩余部分
2).同时Expanded--c2c3,最终c2c3的长度是一样的
3).同时Expanded--c1c2c3,最终c1,c2c3长度都是一样的

张风捷特烈 wechat
-------------本文结束感谢您的阅读 @张风捷特烈-------------
0%