Flutter開發實戰初級(2)佈局詳解github
本篇博客Demo下載點擊這裏:Flutter佈局Demo微信
首先新建一個Flutter項目 我這裏命名爲flutter_layoutdemo, less
接下來咱們建立一個用來練習佈局的layout_demo.dart文件,直接按快捷鍵「Command + N」iphone
而後找到main.dart裏面的MyApp類,替換掉系統默認的代碼,以下圖所示: ide
替換掉以後,咱們直接按快捷鍵「Control+R」 編譯運行到模擬器上面,能夠選擇安卓或者iOS模擬器,也能夠選擇運行在真機上面,以下圖選擇你想運行的模擬器: 佈局
這裏我選擇的是iphone 11 模擬器,運行結果以下:post
接下來咱們在layoutDemo類的build
方法裏面加入一些小部件
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Center(
child: Text('kongyulu'),
),
);
}
}
複製代碼
"Control + R " 編譯運行
其實咱們還能夠經過alignment
屬性是佈局居中顯示,這個相似於IOS 的UILabel的對齊屬性。這樣咱們能夠修改代碼以下:
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
alignment: Alignment(0.0, 0.0),
child: Text('kongyulu2')
);
}
複製代碼
咱們熱更新一下,能夠看到效果以下:
下面咱們簡單介紹一下aligment屬性: 實際上咱們上面代碼用的相對佈局,座標原點在中心,咱們aligment屬性 Alignment(x,y)傳入x,y的座標,這裏傳入(0,0)標識在中心位置,以下圖所示:
如上圖所示,Alignment(-1,-1)標識在左上角,Alignment(1,1)在右下角,Alignment(-1,1)在左下角,Alignment(1,-1)在右上角,下面咱們能夠簡單驗證一下
若是咱們把alignment屬性改成Alignment(1,0),效果以下:
若是咱們把alignment屬性改成Alignment(-1,-1),效果以下:
由此咱們能夠知道(-1,-1)在左上角, (1,1)在右上角,
接下來咱們講解一下橫向佈局Row,咱們修改一下代碼,增長一個Row佈局,代碼以下:
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
alignment: Alignment(0.0, 0.0),
child: Row(
children: <Widget>[
Icon(Icons.add),
Icon(Icons.access_alarm),
Icon(Icons.account_balance_wallet),
],
)
);
}
}
複製代碼
熱更新一下,效果以下:
Row表示橫向佈局,裏面須要傳入一個Widget數組,數組裏面的Widget小部件都橫向排列。咱們能夠看到小部件默認有點小,咱們來修改一下大小將size改成80
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
alignment: Alignment(0.0, 0.0),
child: Row(
children: <Widget>[
Icon(Icons.add,size: 80,),
Icon(Icons.access_alarm,size: 80,),
Icon(Icons.account_balance_wallet,size: 80,),
],
)
);
}
}
複製代碼
從新運行一下效果以下:
若是咱們想跟裏面的小部件添加背景顏色,咱們只須要將這個小部件放到一個新的Container容器裏面包裝一下,便可使用Container裏面的相關屬性,設置顏色等屬性。
咱們再修改一下代碼,給小部件添加背景顏色:
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
alignment: Alignment(0.0, 0.0),
child: Row(
children: <Widget>[
Container(child:Icon(Icons.add,size: 80,) ,color: Colors.blue,)
,
Container(child:Icon(Icons.access_alarm,size: 80,) ,color: Colors.yellow,)
,
Container(child:Icon(Icons.account_balance_wallet,size: 80,) ,color: Colors.green,)
,
],
)
);
}
}
複製代碼
從新運行一下效果以下:
縱向佈局時垂直方向的佈局,更橫向佈局相對應。咱們只須要將上面的橫向佈局代碼的Row改成Column,以下:
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
alignment: Alignment(0.0, 0.0),
child: Column(
children: <Widget>[
Container(child:Icon(Icons.add,size: 80,) ,color: Colors.blue,)
,
Container(child:Icon(Icons.access_alarm,size: 80,) ,color: Colors.yellow,)
,
Container(child:Icon(Icons.account_balance_wallet,size: 80,) ,color: Colors.green,)
,
],
)
);
}
}
複製代碼
熱更新一下,咱們來看一下效果:
咱們再將上面的代碼修改成Stack層級佈局看看什麼效果,修改代碼以下:
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
alignment: Alignment(0.0, 0.0),
child: Stack(
children: <Widget>[
Container(child:Icon(Icons.add,size: 80,) ,color: Colors.blue,)
,
Container(child:Icon(Icons.access_alarm,size: 80,) ,color: Colors.yellow,)
,
Container(child:Icon(Icons.account_balance_wallet,size: 80,) ,color: Colors.green,)
,
],
)
);
}
}
複製代碼
咱們快捷鍵「Command+||」 熱更新一下,運行效果以下:
原本是三個,咱們只看到了最後一個小部件,說明另外兩個被遮擋了,咱們來修改一下每一個小部件的大小:
由此咱們能夠知道 Row橫向佈局對應x軸,Column縱向佈局對應y軸,Stack層次佈局對應z軸,咱們由x,y,z能夠很容易佈局想要的效果。
咱們的Row,Column都有兩個很是重要的屬性:主軸mainAxisAlignment
和 交叉軸
其中主軸須要傳入一個對象,咱們查看源碼能夠看到:
主軸屬性傳入一個MainAxisAlignment
對象,咱們能夠看到它有下面結構屬性:
若是Row橫向佈局,則是沿着x軸從左到右橫着居中,靠右對齊排列顯示
若是是Column縱向佈局,則是沿着y軸從上往下,縱向居中, 而且靠底部對齊顯示
若是Row橫向佈局,則水平方向剩下的空間平均分配在每一個空間的周圍
若是是Column縱向佈局,則垂直方向剩下的空間平均分配在每一個空間的周圍
若是是Row佈局,MainAxisAlignment.start
主軸效果以下:
MainAxisAlignment.start
主軸效果以下:
CrossAxisAlignment交叉軸擁有的屬性以下:
交叉軸默認的屬性是center
居中顯示
textBaseline: TextBaseline.alphabetic
屬性,配合使用,由於baseline屬性須要針對文本才能體現效果,因此咱們還須要在每一個小部件裏面增長一個文本標籤主軸爲x軸,沿交叉軸y軸方向底部對齊
縱向佈局時,baseline
屬性使字體沿交叉軸左對齊
咱們再來看一下去掉baseline屬性的效果:
Expanded 是一種比較靈活的佈局方案,它使得子部件隨之父控件的大小自動填充
咱們接下來將上面的代碼修改一下,將每一個小部件放入Expanded佈局中,修改後代碼以下:
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
alignment: Alignment(0.0, 0.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: <Widget>[
Expanded(child: Container(child:Text('孔雨露',style: TextStyle(fontSize: 15),) ,color: Colors.blue,height: 80,),)
,
Expanded(child:Container(child:Text('努力',style: TextStyle(fontSize: 30),) ,color: Colors.yellow,height: 80,),)
,
Expanded(child: Container(child:Text('堅持',style: TextStyle(fontSize: 60),) ,color: Colors.green,height: 80,),)
,
],
)
);
}
}
複製代碼
運行效果以下:
咱們將上面的代碼的佈局Column改成Row橫向佈局,效果以下:
由此咱們知道,若是咱們設置了Expanded
自動填充,假設咱們使用Row橫向佈局咱們不須要設置寬度(就算設置了寬度也不會生效,沒有意義),沿主軸x軸每一個子部件自動填充拉伸滿,不會在主軸方向留下空隙,同理,若是是縱向佈局,則設置Expanded
自動填充後,不須要設置高度(就算設置了高度也不會生效,沒有意義),沿主軸y會自動填充拉伸。
這個屬性對應咱們文字很長時,會根據寬度自動換行,以下圖:
接下來,若是咱們看一下若是上面的三個小部件,不是每一個都使用expanded佈局呢,如今咱們改一下代碼,把中間的那個小部件改成不是expanded佈局。
咱們將上面的代碼簡化一下,改成以下:
Widget build(BuildContext context) {
return Container(
color: Colors.white,
alignment: Alignment(0.0, 0.0),
child: Container(child:
Icon(Icons.add,size: 30,),height: 40,
color:Colors.blue,)
);
}
複製代碼
運行效果以下:
咱們通常用alignment根據比例來顯示位置,