10

Flutter 组件 | Flex 弹性布局

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzI0NjU3MDA4NQ%3D%3D&%3Bmid=2247484731&%3Bidx=1&%3Bsn=fde9e33f536705b05a0805f617c0e1c3
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

1.Flex的属性一览

Flex 是 Column 和 Row 的父类,其中 Row 的 direction 是水平, Column是竖直。其他的属性都是类似的,相当于 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

1enum Axis {
2  horizontal,//水平
3  vertical,//竖直
4}

也就是水平排放还是竖直排放,可以看出默认情况下都是主轴顶头,交叉轴居中

比如horizontal下主轴为水平轴,交叉轴则为竖直。也就是水平顶头,竖直居中

ARVzUnB.png!mobile

1var direction =[Axis.horizontal,Axis.vertical];
2var show = MultiShower(direction,(e){
3  return Flex(
4    direction: e,
5    children: <Widget>[redBox,blueBox,yellowBox,greenBox],
6
7  );
8},color: Colors.black12,width: 300,height: 200);
9
10var redBox= Container(
11  color: Colors.red,
12  height: 50,
13  width: 50,
14);
15
16var blueBox= Container(
17  color: Colors.blue,
18  height: 30,
19  width: 60,
20);
21
22var yellowBox= Container(
23  color: Colors.yellow,
24  height: 50,
25  width: 100,
26);
27
28var greenBox= Container(
29  color: Colors.green,
30  height: 60,
31  width: 60,
32);

3.主轴方向: mainAxisAlignment

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

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

22QrIrf.png!mobile

1testMainAxisAlignment(){
2  var redBox= Container(
3    color: Colors.red,
4    height: 50,
5    width: 50,
6  );
7
8  var blueBox= Container(
9    color: Colors.blue,
10    height: 30,
11    width: 60,
12  );
13
14  var yellowBox= Container(
15    color: Colors.yellow,
16    height: 10,
17    width: 10,
18  );
19
20  var greenBox= Container(
21    color: Colors.green,
22    height: 50,
23    width: 10,
24  );
25
26  var mainAxisAlignment =[
27  MainAxisAlignment.start,MainAxisAlignment.center,
28  MainAxisAlignment.end,MainAxisAlignment.spaceAround,
29  MainAxisAlignment.spaceBetween,MainAxisAlignment.spaceEvenly];
30
31  var show = MultiShower(mainAxisAlignment,(e){
32    return Flex(
33      direction: Axis.horizontal,
34      mainAxisAlignment: e,
35      children: <Widget>[redBox,blueBox,yellowBox,greenBox],
36
37    );
38  },color: Colors.black12,width: 200,height: 150);
39  return show;
40}

4.交叉轴方向: crossAxisAlignment

1enum CrossAxisAlignment {
2  start,//顶头
3  end,//接尾
4  center,//居中
5  stretch,//伸展
6  baseline,//基线
7}

还是水平为例,交叉轴便是竖轴,这里可以看出他们的布局行为

其中需要注意的是 CrossAxisAlignment.baseline 使用时必须有 textBaseline

其中textBaseline确定对齐的是那种基线,分为 alphabeticideographic

qiEFjuQ.png!mobile

1testCrossAxisAlignment(){
2  var redBox= Container(
3    color: Colors.red,
4    height: 50,
5    width: 50,
6  );
7
8  var blueBox= Container(
9    color: Colors.blue,
10    height: 30,
11    width: 60,
12  );
13
14  var yellowBox= Container(
15    color: Colors.yellow,
16    height: 10,
17    width: 10,
18  );
19
20  var greenBox= Container(
21    color: Colors.green,
22    height: 50,
23    width: 10,
24  );
25
26  var crossAxisAlignment =[CrossAxisAlignment.start,CrossAxisAlignment.center,
27    CrossAxisAlignment.end,CrossAxisAlignment.stretch,CrossAxisAlignment.baseline];
28
29  var show = MultiShower(crossAxisAlignment,(e){
30    return Flex(
31      direction: Axis.horizontal,
32      crossAxisAlignment: e,
33      textBaseline: TextBaseline.alphabetic,//基线类型
34      children: <Widget>[redBox,blueBox,yellowBox,greenBox],
35
36    );
37  },color: Colors.black12,width: 200,height: 140);
38
39  return show;
40}

5.主轴尺寸: mainAxisSize

1enum MainAxisSize {
2  min,
3  max,
4}

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

ymyyE3j.png!mobile

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

EzAvQjB.png!mobile

1testMainAxisSize(){
2  var redBox= Container(
3    color: Colors.red,
4    height50,
5    width50,
6  );
7
8  var blueBox= Container(
9    color: Colors.blue,
10    height30,
11    width60,
12  );
13
14  var yellowBox= Container(
15    color: Colors.yellow,
16    height10,
17    width10,
18  );
19
20  var greenBox= Container(
21    color: Colors.green,
22    height50,
23    width10,
24  );
25
26  return Center(child: Flex(
27    direction: Axis.horizontal,
28    mainAxisSize: MainAxisSize.max,
29    children<Widget>[redBox,blueBox,yellowBox,greenBox],
30
31  ),);
32}
33

6.文字方向: textDirection

1enum TextDirection {
2  ltr,//从左到右
3  rtl,//从右到左
4}

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

Jn22aeF.png!mobile

1testTextDirection(){
2  var redBox= Container(
3    color: Colors.red,
4    height: 50,
5    width: 50,
6  );
7
8  var blueBox= Container(
9    color: Colors.blue,
10    height: 30,
11    width: 60,
12  );
13
14  var yellowBox= Container(
15    color: Colors.yellow,
16    height: 10,
17    width: 10,
18  );
19
20  var greenBox= Container(
21    color: Colors.green,
22    height: 50,
23    width: 10,
24  );
25
26  var textDirection =[TextDirection.ltr,TextDirection.rtl];
27  var show = MultiShower(textDirection,(e){
28    return Flex(
29      direction: Axis.horizontal,
30      textDirection: e,
31      children: <Widget>[redBox,blueBox,yellowBox,greenBox],
32
33    );
34  },color: Colors.black12,width: 200,height: 140);
35  return show;
36}

7.竖直方向排序: verticalDirection

1enum VerticalDirection{
2    up,
3    down,
4}

R3QzeeA.png!mobile

1testVerticalDirection(){
2  var redBox= Container(
3    color: Colors.red,
4    height: 50,
5    width: 50,
6  );
7
8  var blueBox= Container(
9    color: Colors.blue,
10    height: 30,
11    width: 60,
12  );
13
14  var yellowBox= Container(
15    color: Colors.yellow,
16    height: 10,
17    width: 10,
18  );
19
20  var greenBox= Container(
21    color: Colors.green,
22    height: 50,
23    width: 10,
24  );
25
26  var verticalDirection =[VerticalDirection.up,VerticalDirection.down];
27
28  var show = MultiShower(verticalDirection,(e){
29    return Flex(
30      direction: Axis.vertical,
31      verticalDirection: e
32      children: <Widget>[redBox,blueBox,yellowBox,greenBox],
33
34    );
35  },color: Colors.black12,width: 200,height: 140);
36
37  return show;
38}

8.基线对齐方式: textBaseline

1enum TextBaseline {
2  alphabetic,
3  ideographic,
4}

ZJ3Mzyy.png!mobile

1testTextBaseline(){
2  var redBox= Text(
3    "张风捷特烈",style: TextStyle(fontSize: 20,backgroundColor: Colors.red),
4  );
5
6  var blueBox= Text(
7    "toly",style: TextStyle(fontSize: 50,backgroundColor: Colors.blue),
8  );
9
10  var yellowBox=  Text(
11    "1994",style: TextStyle(fontSize: 30,backgroundColor: Colors.green),
12  );
13
14  var textBaseline =[TextBaseline.alphabetic,TextBaseline.ideographic];
15
16  var show = MultiShower(textBaseline,(e){
17    return Flex(
18      direction: Axis.horizontal,
19      crossAxisAlignment: CrossAxisAlignment.baseline,
20      textBaseline: e,
21      children: <Widget>[redBox,blueBox,yellowBox],
22    );
23  },color: Colors.black12,width: 300,height: 140);
24
25  return show;
26}

9. Expanded与Flex的搭配

要一点是关于Expanded 组件,它能与 Flex 布局结合,对孩子组件区域进行延展。

1c1:绿色  c2:红色  c3:黄色
21).Expanded--c2:c1和c3将不变,c2延伸自己占满剩余部分
32).同时Expanded--c2和c3,最终c2和c3的长度是一样的
43).同时Expanded--c1,c2和c3,最终c1,c2,c3长度都是一样的

eaIVji2.png!mobile

10.用Flex布局写个小例子

下面就用一个布局来实际看一下 Flex 的使用。

Q7BNbmm.png!mobile

首先简单的分析一下

MrAreiu.png!mobile

11.由上中下三行,可以用Column
22.第一行由图标,文字和文字组成,其中两头分处左右,可以用Expanded处理  
33.中间比较复杂由一个Row中包含两部分,左边是一个两行Column的内容,右边是文字  
44.底部是一个Row,主轴对齐是start

布局代码

1showItem() {
2  var infoStyle = TextStyle(color: Color(0xff999999), fontSize: 13);
3  var littleStyle = TextStyle(color: Colors.black, fontSize: 16);
4
5  var top = Row(//顶部,通过Flex布局的Row进行横向排列,Expanded中间
6    children: <Widget>[
7      Image.asset("images/icon_head.png", width: 20, height: 20),
8      Expanded(
9        child: Padding(
10          child: Text("张风捷特烈"),
11          padding: EdgeInsets.only(left: 4),
12        ),
13      ),
14      Text(
15        "Flutter/Dart",
16        style: infoStyle,
17      )
18    ],
19  );
20
21  var content = Column(//中间文字内容,交叉轴为start
22    mainAxisSize: MainAxisSize.min,
23    crossAxisAlignment: CrossAxisAlignment.start,
24    children: <Widget>[
25      Text(
26        "[Flutter必备]-Flex布局完全解读",
27        style: littleStyle,
28        maxLines: 2,
29        overflow: TextOverflow.ellipsis,
30      ),
31      Padding(
32        child: Text("也就是水平排放还是竖直排放,可以看出默认情况下都是主轴顶头,"
33            "交叉轴居中比如horizontal下主轴为水平轴,交叉轴则为竖直。也就是水平顶头,竖直居中"
34            "这里使用MultiShower快速展示,更好的对比出不同之处",
35            style: infoStyle, maxLines: 2, overflow: TextOverflow.ellipsis),
36        padding: EdgeInsets.only(top: 5),
37      ),
38    ],
39  );
40
41  var center = Row(//中间的部分
42    children: <Widget>[
43      Expanded(
44          child: Padding(
45        child: content,
46        padding: EdgeInsets.all(5),
47      )),
48      ClipRRect(
49        borderRadius: BorderRadius.all(Radius.circular(5)),
50        child: Image.asset("images/wy_300x200.jpg",
51          width: 80, height: 80, fit: BoxFit.cover),)
52    ],
53  );
54
55  var end = Row(//底部
56    children: <Widget>[
57      Icon(
58        Icons.grade,
59        color: Colors.green,
60        size: 20,
61      ),
62      Text(
63        "1000W",
64        style: infoStyle,
65      ),
66      Padding(child:Icon(Icons.tag_faces, color: Colors.lightBlueAccent, size: 20),
67          padding: EdgeInsets.symmetric(horizontal: 5),),
68      Text("2000W", style: infoStyle),
69    ],
70  );
71
72  var result = Card(//总体拼合
73      child: Container(
74          height: 160,
75          color: Colors.white,
76          padding: EdgeInsets.all(10),
77          child: Column(children: <Widget>[top, Expanded(child: center), end])));
78  return result;
79}


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK