彈性布局允許子組件按照一定比例來分配父容器空間
創(chuàng)新互聯(lián)公司專注于皮山企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),商城網(wǎng)站建設(shè)。皮山網(wǎng)站建設(shè)公司,為皮山等地區(qū)提供建站服務(wù)。全流程按需開發(fā),專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)
Flex組件和Row、Column屬性主要的區(qū)別就是多一個direction。
當(dāng)direction的值為Axis.horizontal的時候,則是Row。
當(dāng)direction的值為Axis.vertical的時候,則是Column。
它們之中都有主軸(MainAxis)和交叉軸(CrossAxis)的概念:
Row可以沿水平方向排列其子widget。定義如下:
示例1 - 基本使用
示例2 - 基線對齊
基線是英文字母X的下端兩點連成的一條線
示例3 - 水平方向包裹
Column可以沿垂直方向排列其子widget。定義如下:
Column 基本使用 示例
再看一個示例
運行效果如下:
我們發(fā)現(xiàn)文本并沒有居中?
解釋:
實際上,Row和Column都只會在主軸方向占用盡可能大的空間,而交叉軸的長度則取決于他們最大子元素的長度。如果我們想讓本例中的兩個文本控件在整個手機屏幕中間對齊,我們有兩種方法:
運行效果如下:
如果Row里面嵌套Row,或者Column里面再嵌套Column,那么只有最外面的Row或Column會占用盡可能大的空間,里面Row或Column所占用的空間為實際大小,下面以Column為例說明
如果要讓里面的Column占滿外部Column,可以使用Expanded 組件:
相對于iOS開發(fā),F(xiàn)lutter的布局更具有靈活性,每個頁面設(shè)計都不一樣,相同頁面可選擇的布局方式也不一樣,如果單純的說應(yīng)該如何去布局,我覺得不現(xiàn)實,大家可以參考下 Flutter官方的布局教程 。接下來,筆者,通過項目中的一個頁面,來一步一步的拆解布局的流程。整個過程,基本上按照拆解、組件封裝、具體布局這三步來的。
根據(jù)設(shè)計圖,可以看出整體可以分成兩部分,上面一部分是系統(tǒng)介紹模塊,下面一部分是真正的登錄內(nèi)容,因為涉及到疊加,因此考慮用Stack;
系統(tǒng)介紹模塊部分:整體也是涉及到疊加,考慮用Stack,分為四部分。最底部漸變色背景用一個contanier,無須指定位置,全視圖擴展;載放logo圖標(biāo)在上一層,用Image。最后兩個Text同級放在最上層。Image,Text各用Positioned包裹去指定位置。
登錄內(nèi)容模塊是最外層是一個Contanier容器,去控制背景色和圓角。然后是一個Column元素,逐行排列。
第一行為Image,
第二行為Text,
第三行可以看成一個小Column,分兩塊進行布局
第四行可以看成一個小Column,分兩塊進行布局
第五行可以看作一個TextButton,
第六行可以看作一個Row,分三塊進行布局
通過上面這樣一步一步的分析后,基本上對大致的布局有了一個了解,最外層的控件大致選對(只要能實現(xiàn)的話,就是復(fù)雜度以及效率的問題),然后一步一步的拆解每一行的元素,如果有重復(fù)的或者覺得可以封裝出來的部分,則進行下一步。
每一行的拆解,大致也是按照這個思路來進行,因此筆者在這里就不做講解了。
在做到第三第四行的時候,發(fā)現(xiàn)這兩個很相似,而且設(shè)計到一些交互邏輯,筆者就想對第三第四行的這種展示進行封裝,覺得今后的布局可能會用到,因此在這一步,可以先把這一塊兒抽離出一個控件。利用TextField來實現(xiàn)這種輸入操作,具體的實現(xiàn)筆者不再詳細(xì)的描述了。
經(jīng)過這一步,整體的規(guī)劃設(shè)計圖已經(jīng)有了,各個組件也都有了,接下來的工作就是組裝了。
具體布局設(shè)計到一些細(xì)節(jié)的地方,例如整體Column的居中對齊(crossAxisAlignment)、間隔(Padding或Container包裹,筆者更喜歡用SizedBox占位)、居左居右居中(Align)、點擊事件(GestureDetector)以及圓角(BorderRadius)等一些特殊情況。
像第六行row是放在底部的,就可以在第六行前面增加一個Spacer()去填充空白區(qū)域。
對文字顏色大小等,可以用TextStyle直接設(shè)置。
對于輸入框的刪除按鈕,可以用Offstage這種Flutter特有的控制顯示隱藏的控件。
流式布局(Liquid)的特點(也叫"Fluid") 是頁面元素的寬度按照屏幕分辨率進行適配調(diào)整,但整體布局不變。柵欄系統(tǒng)(網(wǎng)格系統(tǒng)),用戶標(biāo)簽等。在Flutter中主要有Wrap和Flow兩種Widget實現(xiàn)。
在介紹Row和Colum時,如果子widget超出屏幕范圍,則會報溢出錯誤,在Flutter中通過Wrap和Flow來支持流式布局,溢出部分則會自動折行。
上述有很多屬性和Row的相同,其意義其實也是相同的,這里我就不一一介紹了,主要介紹下不同的屬性:
我們一般很少會使用Flow,因為其過于復(fù)雜,需要自己實現(xiàn)子widget的位置轉(zhuǎn)換,在很多場景下首先要考慮的是Wrap是否滿足需求。Flow主要用于一些需要自定義布局策略或性能要求較高(如動畫中)的場景。Flow有如下優(yōu)點:
我們對六個色塊進行自定義流式布局:
實現(xiàn)TestFlowDelegate:
可以看到我們主要的任務(wù)就是實現(xiàn)paintChildren,它的主要任務(wù)是確定每個子widget位置。由于Flow不能自適應(yīng)子widget的大小,我們通過在getSize返回一個固定大小來指定Flow的大小,實現(xiàn)起來還是比較麻煩的。
Stack 組件是一種層疊式布局,即組件覆蓋另一個組件,覆蓋的順序取決于在children中放置的順序,使用場景比如在圖片上加上一些文字描述,即將文本W(wǎng)idget覆蓋在圖片組件,詳見下面的小例。
Stack 是可以將視圖根據(jù)children中子組件的順序進行疊加的組件,根據(jù)子組件是否被Positioned包裹判斷布局的方式
Stack 的fit 屬性用來控制Stack如何將自己的父級組件的尺寸約束傳達給無位置組件,通過fit屬性約束Stack中無位置組件的尺寸,默認(rèn)值是 StackFie.loose. 如:Stack的父級組件要求Stack的尺寸是 200x200 ~ 500x500.在默認(rèn)的StackFit.loose(寬松狀態(tài))下,Stack 可以運行其children在不違反父級約束的前提下,自由選擇尺寸,即可在0x0~500x500的范圍內(nèi)任意選擇。相反如何傳入的fit是StackFit.expand(擴張狀態(tài))下,則會要求所有無位置children必須占滿父級約束的最大空間,即尺寸必須為500x500,最后當(dāng)傳入的StackFit.passthrough(穿透狀態(tài))時,Stack會將自己父級組件的尺寸約束直接傳遞給子組件,即保留原有的200x200 ~ 500x500的約束。
StackFie.loose 和StackFit.passthrough的效果
StackFit.expand的效果
表格布局和線性布局比較相似,只是使用起來更簡潔一些。
本地Flutter 2.10.1,Mac版Android Studio Bumblebee | 2021.1.1 Patch 2
我是小栗子,初學(xué)Flutter ,文章會根據(jù)學(xué)習(xí)進度不定時更新,請多多指教~~