0.前言
Flex布局是Flutter的五虎上將之一,虎父無犬子穆壕,其子Row和Column也能力非凡
你有沒有被mainAxisAlignment,crossAxisAlignment弄得暈頭轉(zhuǎn)向,本文將助你將他們納入麾下署照。
先看一下父子三人在Flutter布局體系中的位置:多子組件布局
1.Flex的屬性一覽
屬性名 | 類型 | 默認(rèn)值 | 簡介 |
---|---|---|---|
direction | Axis | @required | 軸向 |
mainAxisAlignment | MainAxisAlignment | start | 主軸方向?qū)R方式 |
crossAxisAlignment | CrossAxisAlignment | center | 交叉軸方向?qū)R方式 |
mainAxisSize | MainAxisSize | max | 主軸尺寸 |
textDirection | TextDirection | null | 文本方向 |
verticalDirection | VerticalDirection | down | 豎直方向 |
textBaseline | TextBaseline | null | 基線類型 |
children | List<Widget> | <Widget>[] | 內(nèi)部孩子 |
2.軸向:direction:Axis
enum Axis {
horizontal,//水平
vertical,//豎直
}
也就是水平排放還是豎直排放臭脓,可以看出默認(rèn)情況下都是主軸頂頭,交叉軸居中
比如horizontal下主軸為水平軸酗钞,交叉軸則為豎直。也就是水平頂頭来累,豎直居中
這里使用MultiShower快速展示,更好的對比出不同之處砚作,MultiShower詳見
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
主軸方向的排布規(guī)則,這里以水平為例,主軸為水平方向嘹锁。豎直類比即可
enum MainAxisAlignment {
start,//頂頭
end,//接尾
center,//居中
spaceBetween,//頂頭接尾葫录,其他均分
spaceAround,//中間的孩子均分,兩頭的孩子空一半
spaceEvenly,//均勻平分
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
使用時(shí)必須有textBaseline
其中textBaseline確定對齊的是那種基線,分為alphabetic
和ideographic
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,
}
當(dāng)父容器的寬未約束,Flex默認(rèn)會(huì)將自身盡可能延伸米同,這便是MainAxisSize.max
此時(shí)改為MainAxisSize.min時(shí),它不會(huì)延伸自己的區(qū)域骇扇,自會(huì)包裹內(nèi)容
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,//從右到左
}
這個(gè)非常好理解,不多言了
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,
}
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,
}
testTextBaseline(){
var redBox= Text(
"張風(fēng)捷特烈",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;
}
至此面粮,F(xiàn)lutter中的Flex布局就已經(jīng)完全解讀完了少孝。
其中Flutter的孩子Row是direction: Axis.horizontal,
Column是direction: Axis.vertical,
其他的屬性都是類似的,相當(dāng)于Flex的簡化版熬苍,所以Flex在手韭山,天下我有。
Expanded與Flex的搭配--- [更新于2019.1.22]
還要一點(diǎn)是關(guān)于Expanded冷溃,也比較保用钱磅,它能與Flex布局結(jié)合,變更孩子尺寸
c1:綠色 c2:紅色 c3:黃色
1).Expanded--c2:c1和c3將不變似枕,c2延伸自己占滿剩余部分
2).同時(shí)Expanded--c2和c3盖淡,最終c2和c3的長度是一樣的
3).同時(shí)Expanded--c1,c2和c3凿歼,最終c1,c2褪迟,c3長度都是一樣的
9.用Flex布局寫個(gè)小例子
光說不練假把式,光練不說空把式,下面就用一個(gè)布局來實(shí)際看一下Flex的強(qiáng)大
- 首先簡單的分析一下
1.由上中下三行,可以用Column
2.第一行由圖標(biāo)答憔,文字和文字組成味赃,其中兩頭分處左右,可以用Expanded處理
3.中間比較復(fù)雜由一個(gè)Row中包含兩部分虐拓,左邊是一個(gè)兩行Column的內(nèi)容,右邊是文字
4.底部是一個(gè)Row,主軸對齊是start
- 布局代碼
showItem() {
var infoStyle = TextStyle(color: Color(0xff999999), fontSize: 13);
var littleStyle = TextStyle(color: Colors.black, fontSize: 16);
var top = Row(//頂部,通過Flex布局的Row進(jìn)行橫向排列,Expanded中間
children: <Widget>[
Image.asset("images/icon_head.png", width: 20, height: 20),
Expanded(
child: Padding(
child: Text("張風(fēng)捷特烈"),
padding: EdgeInsets.only(left: 4),
),
),
Text(
"Flutter/Dart",
style: infoStyle,
)
],
);
var content = Column(//中間文字內(nèi)容,交叉軸為start
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"[Flutter必備]-Flex布局完全解讀",
style: littleStyle,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
Padding(
child: Text("也就是水平排放還是豎直排放心俗,可以看出默認(rèn)情況下都是主軸頂頭,"
"交叉軸居中比如horizontal下主軸為水平軸,交叉軸則為豎直蓉驹。也就是水平頂頭城榛,豎直居中"
"這里使用MultiShower快速展示,更好的對比出不同之處",
style: infoStyle, maxLines: 2, overflow: TextOverflow.ellipsis),
padding: EdgeInsets.only(top: 5),
),
],
);
var center = Row(//中間的部分
children: <Widget>[
Expanded(
child: Padding(
child: content,
padding: EdgeInsets.all(5),
)),
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5)),
child: Image.asset("images/wy_300x200.jpg",
width: 80, height: 80, fit: BoxFit.cover),)
],
);
var end = Row(//底部
children: <Widget>[
Icon(
Icons.grade,
color: Colors.green,
size: 20,
),
Text(
"1000W",
style: infoStyle,
),
Padding(child:Icon(Icons.tag_faces, color: Colors.lightBlueAccent, size: 20),
padding: EdgeInsets.symmetric(horizontal: 5),),
Text("2000W", style: infoStyle),
],
);
var result = Card(//總體拼合
child: Container(
height: 160,
color: Colors.white,
padding: EdgeInsets.all(10),
child: Column(children: <Widget>[top, Expanded(child: center), end])));
return result;
}
結(jié)語
本文到此接近尾聲了,如果想快速嘗鮮Flutter态兴,《Flutter七日》會(huì)是你的必備佳品;如果想細(xì)細(xì)探究它,那就跟隨我的腳步狠持,完成一次Flutter之旅。
另外本人有一個(gè)Flutter微信交流群瞻润,歡迎小伙伴加入喘垂,共同探討Flutter的問題,本人微信號:zdl1994328
绍撞,期待與你的交流與切磋正勒。