Flutter開發實戰初級(2)頁面佈局詳解

  • 初級基礎系列

Flutter開發實戰初級(1)ListView詳解git

Flutter開發實戰初級(2)佈局詳解github

  • 項目實戰系列

Flutter開發實戰 高仿微信(1)首頁swift

Flutter開發實戰 高仿微信(2)發現頁數組

Flutter開發實戰初級(2)頁面佈局詳解

本篇博客Demo下載點擊這裏:Flutter佈局Demo微信

1. Flutter佈局實戰講解

1.1 佈局座標

首先新建一個Flutter項目 我這裏命名爲flutter_layoutdemo, less

新建一個Flutter項目

接下來咱們建立一個用來練習佈局的layout_demo.dart文件,直接按快捷鍵「Command + N」iphone

建立一個用來練習佈局的layout_demo.dart文件

而後找到main.dart裏面的MyApp類,替換掉系統默認的代碼,以下圖所示: ide

替換掉系統默認的代碼

替換掉以後,咱們直接按快捷鍵「Control+R」 編譯運行到模擬器上面,能夠選擇安卓或者iOS模擬器,也能夠選擇運行在真機上面,以下圖選擇你想運行的模擬器: 佈局

選擇你想運行的模擬器

這裏我選擇的是iphone 11 模擬器,運行結果以下:post

iphone 11 模擬器,運行結果

接下來咱們在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')
    );
  }
複製代碼

咱們熱更新一下,能夠看到效果以下:

alignment屬性居中顯示

下面咱們簡單介紹一下aligment屬性: 實際上咱們上面代碼用的相對佈局,座標原點在中心,咱們aligment屬性 Alignment(x,y)傳入x,y的座標,這裏傳入(0,0)標識在中心位置,以下圖所示:

alignment屬性座標詳解

如上圖所示,Alignment(-1,-1)標識在左上角,Alignment(1,1)在右下角,Alignment(-1,1)在左下角,Alignment(1,-1)在右上角,下面咱們能夠簡單驗證一下

若是咱們把alignment屬性改成Alignment(1,0),效果以下:

把alignment屬性改成Alignment(1,0)
若是咱們把alignment屬性改成Alignment(0,1),效果以下:
在這裏插入圖片描述

若是咱們把alignment屬性改成Alignment(-1,-1),效果以下:

把alignment屬性改成Alignment(-1,-1)

由此咱們能夠知道(-1,-1)在左上角, (1,1)在右上角,

1.2 橫向佈局Row

接下來咱們講解一下橫向佈局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

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,),
        ],
      )
    );
  }
}

複製代碼

從新運行一下效果以下:

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,)
          ,

        ],
      )
    );
  }
}
複製代碼

從新運行一下效果以下:

給小部件添加背景顏色

1.3 縱向佈局Column

縱向佈局時垂直方向的佈局,更橫向佈局相對應。咱們只須要將上面的橫向佈局代碼的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,)
          ,

        ],
      )
    );
  }
}
複製代碼

熱更新一下,咱們來看一下效果:

縱向佈局

1.4 層級佈局Stack

咱們再將上面的代碼修改成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+||」 熱更新一下,運行效果以下:

層級佈局stack

原本是三個,咱們只看到了最後一個小部件,說明另外兩個被遮擋了,咱們來修改一下每一個小部件的大小:

修改小部件大小後的stack佈局效果

由此咱們能夠知道 Row橫向佈局對應x軸,Column縱向佈局對應y軸,Stack層次佈局對應z軸,咱們由x,y,z能夠很容易佈局想要的效果。

1.5 主軸 mainAxisAlignment

咱們的Row,Column都有兩個很是重要的屬性:主軸mainAxisAlignment 和 交叉軸

其中主軸須要傳入一個對象,咱們查看源碼能夠看到:

主軸和交叉軸定義

主軸屬性傳入一個MainAxisAlignment對象,咱們能夠看到它有下面結構屬性:

在這裏插入圖片描述

  • MainAxisAlignment.center: 表示沿着主軸方向居中顯示,若是Row橫向佈局,則是沿着x軸從左到右橫着居中排列顯示,若是是Column縱向佈局,則是沿着y軸從上往下,縱向居中顯示

若是Row橫向佈局,則是沿着x軸從左到右橫着居中排列顯示

若是是Column縱向佈局,則是沿着y軸從上往下,縱向居中顯示

  • MainAxisAlignment.end :

若是Row橫向佈局,則是沿着x軸從左到右橫着居中,靠右對齊排列顯示

若是Row橫向佈局,則是沿着x軸從左到右橫着居中,靠右對齊排列顯示

若是是Column縱向佈局,則是沿着y軸從上往下,縱向居中, 而且靠底部對齊顯示

若是是Column縱向佈局,則是沿着y軸從上往下,縱向居中, 而且靠底部對齊顯示

  • MainAxisAlignment.spaceAround: 就是將主軸方向剩下的空間平均分配給每一個子控件。

若是Row橫向佈局,則水平方向剩下的空間平均分配在每一個空間的周圍

水平方向剩下的空間平均分配在每一個空間的周圍

若是是Column縱向佈局,則垂直方向剩下的空間平均分配在每一個空間的周圍

垂直方向剩下的空間平均分配在每一個空間的周圍
在這裏插入圖片描述

  • MainAxisAlignment.spaceBetween: 剩下的空間平均分配到每一個小部件之間的間隔。
    在這裏插入圖片描述

在這裏插入圖片描述

  • MainAxisAlignment.spaceEvently: 剩下空間和小部件一塊兒平均分配,是等間距的分配。

在這裏插入圖片描述
在這裏插入圖片描述

  • MainAxisAlignment.start : 表示主軸開始的方向, 也是默認值

若是是Row佈局,MainAxisAlignment.start 主軸效果以下:

表示主軸開始的方向, 也是默認值
若是是Column佈局, MainAxisAlignment.start 主軸效果以下:
若是是Column佈局,MainAxisAlignment.start主軸效果

1.6 交叉軸 CrossAxisAlignment

CrossAxisAlignment交叉軸擁有的屬性以下:

交叉軸

交叉軸默認的屬性是center 居中顯示

  • CrossAxisAlignment.baseline : 這個baseline屬性不能單獨使用,須要結合其餘屬性配合使用,不然會報錯:
    須要結合其餘屬性配合使用,不然會報錯
    咱們修改一下代碼,增長textBaseline: TextBaseline.alphabetic屬性,配合使用,由於baseline屬性須要針對文本才能體現效果,因此咱們還須要在每一個小部件裏面增長一個文本標籤

主軸爲x軸,沿交叉軸y軸方向底部對齊

主軸爲x軸,沿交叉軸y軸方向底部對齊
咱們將標籤的背景大小設置一致更好對比:
將標籤的背景大小設置一致更好對比

縱向佈局時,baseline屬性使字體沿交叉軸左對齊

縱向佈局時,baseline屬性使字體沿交叉軸左對齊

咱們再來看一下去掉baseline屬性的效果:

去掉baseline屬性的效果

  • CrossAxisAlignment.center :
    在這裏插入圖片描述

在這裏插入圖片描述

  • CrossAxisAlignment.end :
    在這裏插入圖片描述

在這裏插入圖片描述

  • CrossAxisAlignment.start :
    CrossAxisAlignment.start 做爲x軸

Row佈局主軸是x軸,交叉軸是y軸

  • CrossAxisAlignment.stretch :
    在這裏插入圖片描述
    在這裏插入圖片描述

1.7 Expanded自動填充

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,),)
          ,

        ],
      )
    );
  }
}
複製代碼

運行效果以下:

Expended自動填充佈局

咱們將上面的代碼的佈局Column改成Row橫向佈局,效果以下:

沿x軸自動填充

由此咱們知道,若是咱們設置了Expanded自動填充,假設咱們使用Row橫向佈局咱們不須要設置寬度(就算設置了寬度也不會生效,沒有意義),沿主軸x軸每一個子部件自動填充拉伸滿,不會在主軸方向留下空隙,同理,若是是縱向佈局,則設置Expanded自動填充後,不須要設置高度(就算設置了高度也不會生效,沒有意義),沿主軸y會自動填充拉伸。

這個屬性對應咱們文字很長時,會根據寬度自動換行,以下圖:

超過最大寬度後,自動換行

接下來,若是咱們看一下若是上面的三個小部件,不是每一個都使用expanded佈局呢,如今咱們改一下代碼,把中間的那個小部件改成不是expanded佈局。

有一個小部件不使用Expanded屬性

1.8 Alignment屬性

咱們將上面的代碼簡化一下,改成以下:

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屬性

咱們通常用alignment根據比例來顯示位置,

相關文章
相關標籤/搜索