【Flutter 基礎】 檢視佈局-前言

林小帥發表於2021-07-22

這是我參與更文挑戰的第4天,活動詳情檢視: 更文挑戰

注:本文從個人公眾號(島前嶼端)中遷移重新發布

Flutter 是谷歌的移動 UI 框架,可以從單個程式碼庫快速的為移動端(iOS & Android)、Web、桌面端、嵌入式裝置上構建高質量的原生使用者介面和應用程式。


在學習 Flutter 的過程中也看到一些人對於 Flutter 的議論。他們大多覺得 Flutter 不夠友好、括號太多了,導致看起來程式碼非常複雜,對此嗤之以鼻並以唱衰之

當然也有一些人認為,不再以 xml 的方式實現結構佈局且以程式碼邏輯來驅動和構建佈局的方式對於一些審美感不高的人是一種樂於接受的方式。

所謂江湖紛雜,流派眾多,也是各花入各眼。孰對孰錯並無絕對之說。

而我的看法則是較為中立,應該是各取一半吧:

以程式碼驅動構建佈局確實是可以省下對於佈局的搔首撓耳之苦,但對於較為複雜的結構程式碼驅動的形式就顯得沒那麼遊刃有餘了。當然在一些特性上相對傳統確實是較為便捷不可否認。

這段時間學習以來,看過一些大俠們的作品,功力不一般。大多為獨立實現的作品,讓我看了煞是羨慕。

不過說來慚愧我也學了一月有餘,對於 Flutter 的整體認識程度還不是很高,還不能很全面的去講解整個 Flutter 的體系。但我能做到的是將我在學習過程中我遇到的問題、踩到的坑、理解上的問題解決完後,再重新整理輸出出來,以便有需要或有興趣學的少俠們提供幫助參考。

Ok,以上就是我瞎逼逼的廢話了。那麼接下來就來看一看 Flutter 的檢視佈局吧。

檢視的佈局方式

簡單說一下我對 Flutter 檢視佈局的看法,在前篇中我有提到 Flutter 是使用了 Dart 語言進行編寫,所以弱化了檢視編輯的部分。檢視的渲染、結構、佈局都通過程式碼邏輯來生成。

這在一定程度上在檢視結構和邏輯的關聯性是強了,但在直觀佈局結構方面卻弱了,所以就導致在程式碼中會發現巢狀層次很多很深,同時也會對開發者的能力有了一些要求,當然如果有物件導向程式設計的經驗的話,那麼就上手來說問題並不大。

在 Flutter 中主要的佈局方式有兩種:

  • 多子類元素佈局
  • 單子類元素佈局

還有一個比較特殊的 LayoutBuilder,這個主要是構建一個可以依賴父視窗大小的 Widget 樹

此外在官方文件術語描述中將 2 個 Widget 巢狀關係為 Widget 下的子 Widget,這不便於一些已經學過 html 或 xml 的少俠們理解,故在此約定:

約定:在接下來的 《Flutter 檢視佈局》系列文章中我將 widget 下的第一級 widget 稱之為 “子元素” 以便讓少俠們理解。

多子類元素佈局

即,該 Widget 下允許存在多個子 Widget 元素。

多子類元素佈局的 Widget 有 10 種

  • Row 在水平方向上排列子 Widget 元素的列表。
  • Column 在垂直方向上排列子 Widget 元素的列表。
  • ListBody 一個 Widget,它沿著一個給定的軸,順序排列它的子 Widget 元素。
  • ListView 可滾動的列表控制元件。ListView 是最常用的滾動 Widget,它在滾動方向上一個接一個地顯示它的子 Widget 元素。在縱軸上,子元素們被要求填充ListView。
  • Table 為其子 Widget 元素使用表格佈局演算法的 Widget。
  • Wrap 可以在水平或垂直方向多行顯示其子 Widget 元素。
  • Flow 一個可以實現流式佈局演算法的 Widget。
  • Stack 可以允許其子 Widget 元素簡單的堆疊在一起。
  • IndexedStack 從一個子 Widget 元素列表中顯示單個子 Widget 元素的 Stack。
  • CustomMultiChildLayout 使用一個委託來對多個子 Widget 元素進行設定大小和定位的小部件。

每一種 Widget 所實現的佈局方式都不一樣,都有一個主要的實現場景,以及對子 Widget 元素的展示方式

單子類元素佈局

即,該 Widget 下只允許存在一個子 Widget 元素。

單子類元素佈局的 Widget 有 18 種

  • Container 一個擁有繪製、定位、調整大小的 Widget。
  • Padding 可以將其子 Widget 元素新增填充指定的空間的 Widget。
  • Center 將其子 Widget 元素居中顯示在自身內部的 Widget。
  • Align 一個 Widget,它可以將其子 Widget 元素對齊,並可以根據子 Widget 元素的大小自動調整大小。
  • Baseline 根據子 Widget 元素的基線對它們的位置進行定位的 Widget。
  • IntrinsicWidth 一個 Widget,它將它的子 Widget 元素的寬度調整其本身實際的寬度。
  • IntrinsicHeight 一個 Widget,它將它的子 Widget 元素的高度調整其本身實際的高度。
  • AspectRatio 一個 Widget,試圖將子 Widget 元素的大小指定為某個特定的長寬比。
  • Transform 在繪製子 Widget 元素之前應用變換效果的 Widget。
  • Offstage 一個佈局 Widget,可以控制其子 Widget 元素的顯示和隱藏。
  • ConstrainedBox 對其子 Widget 元素施加附加約束的 Widget。
  • FittedBox 按自己的大小調整其子 Widget 元素的大小和位置。
  • LimitedBox 一個當其自身不受約束時才限制其大小的盒子。
  • OverflowBox 對其子 Widget 元素施加不同約束的 Widget,它可能允許子 Widget 元素溢位父級。
  • SizedBox 一個特定大小的盒子。這個 Widget 強制它的子 Widget 有一個特定的寬度和高度。如果寬度或高度為NULL,則此 Widget 將調整自身大小以匹配該維度中的子 Widget 的大小。
  • SizedOverflowBox 一個特定大小的 Widget,但是會將它的原始約束傳遞給它的子 Widget,它可能會溢位。
  • FractionallySizedBox 一個 Widget,它把它的子 Widget 元素放在可用空間的一小部分。關於佈局演算法的更多細節,見 RenderFractionallySizedOverflowBox。
  • CustomSingleChildLayout 一個自定義的擁有單個子元素的佈局 Widget。

每一種 Widget 都會影響其子元素最終的檢視顯示效果,如大小、位置、邊框、背景等

佈局分篇

由於 Widget 佈局的種類多達 28 + 1 種,單篇文章中無法將其一一列舉說完,所以我打算將其分為多篇文章來對其進行說明。

關於單子類元素佈局的 Widget,因部分只會在特定的需求場景中使用,所以這部分我可能不會太深入細說。

在整理之後,我考慮將其按如下分篇:

多子類元素佈局

  • Row、Column(一)
  • ListBody、ListView(二)
  • Table、Wrap、Flow(三)
  • Stack、IndexedStack(四)

單子類元素佈局

  • Container、Padding、Center、Align、Baseline(一)
  • IntrinsicWidth、IntrinsicHeight、AspectRatio (二)
  • Transform、Offstage(三)
  • ConstrainedBox、FittedBox、LimitedBox、OverflowBox (四)
  • SizedBox、SizedOverflowBox、FractionallySizedBox(五)

由於 CustomMultiChildLayout、CustomSingleChildLayout 較為相似,我將它們與 LayoutBuilder 放在一起。

此外我還考慮為了方便各位少俠小夥伴們更直觀的學習和參考,我還將 Flutter 系列的 MyApp 專案同步到了 Github 上,以後如有文章更新都會將文章內的程式碼同步更新到 Github 的專案裡。讓有需要的小夥伴可以 clone 下來學習

當然,在程式碼中我儘量寫了足夠詳細的註釋,也是希望讓少俠 & 小夥伴們不要去猜程式碼,這沒有意義,而是要看懂這是怎麼回事,然後再去嘗試修改程式碼執行得到結果。


Github

Github 地址:github.com/linxsbox/my…

相關文章