Flutter佈局篇(1)–水平和垂直佈局詳解

AWeiLoveAndroid發表於2019-03-03

版權宣告:本文首發在公眾號Flutter那些事,未經授權,嚴禁轉載。

Flutter佈局篇(1)–水平和垂直佈局詳解
Flutter佈局篇(1)–水平和垂直佈局詳解

本文示例程式碼釋出在Github,地址為: https://github.com/AweiLoveAndroid/Flutter-learning/blob/master/README-CN.md

先來看看本文的目錄,如下圖所示:

本文目錄
Flutter佈局篇(1)–水平和垂直佈局詳解

在原生Android開發中,我們經常會用LinearLayout來達到水平或垂直方向的佈局,在Flutter中有兩個常用的元件也能夠做到類似的效果,分別是RowColumn元件,Row元件主要功能是處理水平方向的佈局,Column元件主要功能是處理垂直方向的佈局。下文會具體講解在Flutter中如何使用Row和Column元件實現LinearLayout效果,以及兩者之間的對比,方便大家對比學習。


Flutter佈局篇(1)–水平和垂直佈局詳解

LinearLayout 裡面的android:orientation=”horizontal”屬性相當於Row元件,LinearLayout 裡面的 android:orientation=”vertical”屬性相當於Column元件。

Flutter和LinearLayout的對比圖示如下:

安卓的orientation屬性在Flutter中的體現

Row的使用示例程式碼如下所示:

Row的使用示例程式碼

Column的使用示例程式碼如下所示:

Column的使用示例程式碼

Flutter中的Row以及Column使用效果圖如下所示:

Flutter中的Row以及Column使用效果圖

這裡是Android裡面的使用(由於Flutter效果和Android的是一樣的,後文的安卓效果圖就不再展示了)

Android裡面的使用

Flutter佈局篇(1)–水平和垂直佈局詳解

LinearLayout 裡面的android:layout_width=”wrap_content“或者 android:layout_height=”wrap_content“屬性相當於Row/Column元件裡面的 MainAxisSize.min 屬性。

LinearLayout 裡面的android:layout_width=”match_parent“或者android:layout_height=”match_parent“屬性相當於Row/Column元件裡面的 MainAxisSize.max 屬性。Row/Column元件如果沒有設定mainAxisSize屬性,預設為max屬性值。第二小節中的Row/Column元件我們並沒有設定mainAxisSize屬性,但是我們可以看到它的效果是MainAxisSize.max 屬性的效果(Row自動填充寬為螢幕的寬,Column自動填充高為螢幕的高)。

Flutter和LinearLayout的對比圖示如下:

Flutter和LinearLayout的對比圖

Flutter使用圖解如下:

Flutter中使用 MainAxisSize.max 效果圖
Flutter中使用 MainAxisSize.min 效果圖

Flutter佈局篇(1)–水平和垂直佈局詳解

這個是最複雜的,需要重點掌握。gravity屬性在Android裡面是用於指定控制元件本身或子孩子控制元件的對齊屬性。在Flutter中我們可以使用 Row/Column元件MainAxisAlignment 以及 CrossAxisAlignment 實現控制元件的對齊效果。

Flutter佈局篇(1)–水平和垂直佈局詳解

MainAxisAlignment 是設定主軸方向的對齊方式。如果我們給 Row 元件設定 MainAxisAlignment 屬性,那麼它的主軸為水平方向。如果我們給 Column 元件設定 MainAxisAlignment 屬性,那麼它的主軸為垂直方向。

MainAxisAlignment 有6個屬性值,預設值為start,分別是:

1、MainAxisAlignment.start,將子控制元件放在主軸的起始位置。
2、MainAxisAlignment.end,將子控制元件放在主軸末尾。
3、MainAxisAlignment.center,將子控制元件放在主軸中間位置。
複製程式碼

下面這三個屬性需要特別關注一下:

// 將主軸方向上的空白區域等分,使得子孩子控制元件之間的空白區域相等,
// 兩端的子孩子控制元件都靠近首尾,沒有間隙。
4、MainAxisAlignment.spaceBetween 

// 將主軸方向上的空白區域等分,使得子孩子控制元件之間的空白區域相等,
// 兩端的子孩子控制元件都靠近首尾,首尾子孩子控制元件的空白區域為1/2。
5、MainAxisAlignment.spaceAround 

// 將主軸方向上的空白區域等分,使得子孩子控制元件之間的空白區域相等,包括首尾。
6、MainAxisAlignment.spaceEvenly

複製程式碼
Flutter佈局篇(1)–水平和垂直佈局詳解

CrossAxisAlignment是設定交叉軸方向的對齊方式,比如當前給 Row 元件設定 CrossAxisAlignment 屬性,那麼它的交叉軸為垂直方向。如果我們給 Column 元件設定 CrossAxisAlignment 屬性,那麼它的交叉軸為水平方向。

CrossAxisAlignment 有5個屬性值,預設值為center,分別是:

CrossAxisAlignment.start, 子孩子控制元件顯示在交叉軸的起始位置。
CrossAxisAlignment.end, 子孩子控制元件顯示在交叉軸的末尾位置。
CrossAxisAlignment.center, 子孩子控制元件顯示在交叉軸的中間位置。
CrossAxisAlignment.stretch, 子孩子控制元件完全填充交叉軸方向的空間。
CrossAxisAlignment.baseline, 讓子孩子控制元件的baseline在交叉軸方向對齊。
複製程式碼

具體的示例如下:

(1)Row的子孩子元件對齊

下面這個是Row的子孩子元件對齊的示例:

示例中設定的主軸的屬性值是:MainAxisAlignment.spaceEvenly,交叉軸的屬性值是:CrossAxisAlignment.end

Row的子孩子元件對齊示例程式碼

使用圖示如下圖所示:

Row的子孩子元件對齊效果圖

(2)Column的子孩子元件對齊

下面這個是Column的子孩子元件對齊的示例:

示例中設定的主軸的屬性值是:MainAxisAlignment.spaceEvenly,交叉軸的屬性值是:CrossAxisAlignment.end

Column的子孩子元件對齊示例程式碼

使用圖示如下圖所示:

Column的子孩子元件對齊效果圖

Flutter佈局篇(1)–水平和垂直佈局詳解

在Android中 layout_weight 是LinearLayout裡面的屬性,它是用來給子孩子設定權重的,表示給子孩子按照設定的比例去分配空間。在Flutter中我們可以使用 Expanded 包裹RowColumn元件,使用 Expanded 元件裡面的 flex屬性 去實現同樣的效果。

先來看看Row是會如何給子孩子設定權重的,示例程式碼如下所示:

Row給子孩子設定權重示例程式碼

上例中我寫了一個Row,裡面有3個並排的Icon元件,權重分別是1、2、5,為了好區分,我給每個Icon加了不同的背景顏色。為了程式碼更優雅,我封裝了一個buildIcon(IconData icon, {int flex = 1, Color color}) 函式,IconData是必須傳入的引數; 引數2是權重,預設值為1; 引數3是元件的背景顏色,引數2和引數3是可選引數,可以根據需要進行傳入。

我們看看效果圖,如圖所示:

效果圖

同理,我們只需要把上例中的 new Row替換成new Column就可以實現垂直方向設定權重,如上圖右邊所示。


Flutter佈局篇(1)–水平和垂直佈局詳解

在Flutter中的Row或Column中關於 direction 有2個需要掌握的屬性,分別是:textDirection 以及verticalDirection。其中textDirection屬性在Row元件中起到很大作用,verticalDirection屬性在Column元件中起到很大作用。

textDirection 的屬性值為 TextDirection.ltr,表示所有的子控制元件都是從左到右順序排列,這是預設值。如果為TextDirection.rtl 表示從右邊開始向左邊倒序排列。

verticalDirection 的屬性值為 VerticalDirection.down, 表示所有的子控制元件都是從上到下順序排列。如果為VerticalDirection.up 從底部開始向上倒序排列。

先來看看Row中是如何使用的,我們這裡使用的 textDirection 屬性,是還是拿本章一開始的那個例子做修改,核心程式碼如下所示:

Row中使用textDirection屬性

再來看看Column是如何使用的,可以看出只需要把 textDirection 屬性換成 verticalDirection 就可以了。是不是很簡單?

Column中使用verticalDirection屬性

我們看一下效果圖,如圖所示:

使用效果圖

相關文章