[Flutter必備]-Flex佈局完全解讀

張風捷特烈發表於2019-07-20
0.前言

Flex佈局是Flutter的五虎上將之一,虎父無犬子,其子Row和Column也能力非凡
你有沒有被mainAxisAlignment,crossAxisAlignment弄得暈頭轉向,本文將助你將他們納入麾下。
先看一下父子三人在Flutter佈局體系中的位置:多子元件佈局

[Flutter必備]-Flex佈局完全解讀


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
enum Axis {
  horizontal,//水平
  vertical,//豎直
}
複製程式碼

也就是水平排放還是豎直排放,可以看出預設情況下都是主軸頂頭,交叉軸居中
比如horizontal下主軸為水平軸,交叉軸則為豎直。也就是水平頂頭,豎直居中
這裡使用MultiShower快速展示,更好的對比出不同之處,MultiShower詳見

[Flutter必備]-Flex佈局完全解讀

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

主軸方向的排布規則,這裡以水平為例,主軸為水平方向。豎直類比即可

enum MainAxisAlignment {
  start,//頂頭
  end,//接尾
  center,//居中
  spaceBetween,//頂頭接尾,其他均分
  spaceAround,//中間的孩子均分,兩頭的孩子空一半
  spaceEvenly,//均勻平分
複製程式碼

[Flutter必備]-Flex佈局完全解讀

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
enum CrossAxisAlignment {
  start,//頂頭
  end,//接尾
  center,//居中
  stretch,//伸展
  baseline,//基線
}
複製程式碼

還是水平為例,交叉軸便是豎軸,這裡可以看出他們的佈局行為
其中需要注意的是CrossAxisAlignment.baseline使用時必須有textBaseline
其中textBaseline確定對齊的是那種基線,分為alphabeticideographic

[Flutter必備]-Flex佈局完全解讀

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
enum MainAxisSize {
  min,
  max,
}
複製程式碼

當父容器的寬未約束,Flex預設會將自身儘可能延伸,這便是MainAxisSize.max

[Flutter必備]-Flex佈局完全解讀

此時改為MainAxisSize.min時,它不會延伸自己的區域,自會包裹內容

[Flutter必備]-Flex佈局完全解讀

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
enum TextDirection {
  ltr,//從左到右
  rtl,//從右到左
}
複製程式碼

這個非常好理解,不多言了

[Flutter必備]-Flex佈局完全解讀

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
enum VerticalDirection{
    up,
    down,
}
複製程式碼

[Flutter必備]-Flex佈局完全解讀

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
enum TextBaseline {
  alphabetic,
  ideographic,
}
複製程式碼

[Flutter必備]-Flex佈局完全解讀

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在手,天下我有。


結語

本文到此接近尾聲了,如果想快速嚐鮮Flutter,《Flutter七日》會是你的必備佳品;如果想細細探究它,那就跟隨我的腳步,完成一次Flutter之旅。
另外本人有一個Flutter微信交流群,歡迎小夥伴加入,共同探討Flutter的問題,本人微訊號:zdl1994328,期待與你的交流與切磋。

相關文章