天天看點

Flutter 跨平台架構中的 Widgets,你了解多少?

作者:願天堂沒有代碼

Widgets 是什麼?

Widgets 翻譯成中文就是小插件的意思Widgets 是 Flutter 中使用者界面的基礎;你在 flutter 界面中能夠觀察到的使用者界面,都是 Widgets

當然這些大的 Widgets 又是由一個個的小的Widgets 組成的,而這些小的 Widgets 又是由更小的 Widgets 組成的;這樣就構成了 Widgets 的層次依賴結構,這些層次結構的關聯關系是通過 Widget 中的 child Widget 進行關聯的

在這種層次結構中,子 Widgets 可以共享父 Widgets 的上下文環境

Flutter 中的 Widgets 跟其他語言中的類似的 Widgets 組合有什麼不同呢?

他們最大的不同是,Flutter 中的 Widgets 更多,每個 Widgets 專注的功能更小;即便是一個很小很小功能,在 Flutter 中都可以找到與之對應的 Widgets

這樣做的好處就是,你可以使用不同的,非常基礎的 Widgets 任意組合,進而建構出非常複雜的,個性化的大的 Widgets

當然,它的缺點也非常明顯,就是代碼裡面的 Widgets 太多了,導緻代碼中的層級結構特别的多,可能會看的眼花缭亂

舉個簡單的例子,Container 是 flutter 提供的一個基本的容器 Widget,我們通常這樣來使用它:

Container(
   constraints: BoxConstraints.expand(
     height: Theme.of(context).textTheme.headline4!.fontSize! * 1.1 + 200.0,
   ),
   padding: const EdgeInsets.all(8.0),
   color: Colors.blue[600],
   alignment: Alignment.center,
   child: Text('Hello World',
     style: Theme.of(context)
         .textTheme
         .headline4!
         .copyWith(color: Colors.white)),
   transform: Matrix4.rotationZ(0.1),
 )           

我們向 Container 中傳入了 constraints,padding,color,alignment,child,transform 等資訊

我們先來猜一下,這些資訊中,哪些是用來建構 Widget 的?

大家第一時間想到的應該是 child,它本身就是一個 Widget,用來表示 Container 中包含的子對象,這個很好了解

但是,除了 child 這個 Widget 之外,其他的 constraints,padding,color,alignment,transform 等都是構成 Widget 的元素!

我們來看下 Container 的 build 方法:

Widget build(BuildContext context) {
    Widget? current = child;
if (child == null && (constraints == null || !constraints!.isTight)) {
  current = LimitedBox(
    maxWidth: 0.0,
    maxHeight: 0.0,
    child: ConstrainedBox(constraints: const BoxConstraints.expand()),
  );
}

if (alignment != null)
  current = Align(alignment: alignment!, child: current);

final EdgeInsetsGeometry? effectivePadding = \_paddingIncludingDecoration;
if (effectivePadding != null)
  current = Padding(padding: effectivePadding, child: current);

if (color != null)
  current = ColoredBox(color: color!, child: current);

if (clipBehavior != Clip.none) {
  assert(decoration != null);
  current = ClipPath(
    clipper: \_DecorationClipper(
      textDirection: Directionality.maybeOf(context),
      decoration: decoration!,
    ),
    clipBehavior: clipBehavior,
    child: current,
  );
}

if (decoration != null)
  current = DecoratedBox(decoration: decoration!, child: current);

if (foregroundDecoration != null) {
  current = DecoratedBox(
    decoration: foregroundDecoration!,
    position: DecorationPosition.foreground,
    child: current,
  );
}

if (constraints != null)
  current = ConstrainedBox(constraints: constraints!, child: current);

if (margin != null)
  current = Padding(padding: margin!, child: current);

if (transform != null)
  current = Transform(transform: transform!, alignment: transformAlignment, child: current);

return current!;           

從代碼中可以看到,Container 先是建立了 LimitedBox,然後将其嵌入到 Align 中,再依次嵌入到 Padding,ColoredBox,ClipPath,DecoratedBox,ConstrainedBox,Padding 和 Transform 中;這些所有的對象都是 Widget

這裡應該可以了解 Flutter 中 Widget 的設計思想了;在 Flutter 中一切皆可為 Widget

Widgets 的可擴充性

和其他的編譯成原生語言特性的跨平台實作如 React native 相比,Flutter 對于每個 UI 都有自己的實作,而不是依賴于作業系統提供的接口

這樣做的好處就是一切都是由 Flutter 自己控制的,使用者可以在 Flutter 的基礎上進行無限擴充,而不用受限于系統底層的實作限制

另一方面,這樣可以減少 Flutter 在呈現過程中在 Flutter 代碼和平台代碼之間來回轉換,減少了性能瓶頸,提升效率

最後,因為 UI 的實作和底層的作業系統是分離的,是以 Flutter 的 APP 在不同的平台上面可以有統一的外觀和實作,可以保證風格的統一

Widgets 的狀态管理

Widgets 表示的是不可變的使用者 UI 界面結構;雖然結構是不能夠變化的,但是 Widgets 裡面的狀态是可以動态變化的

根據 Widgets 中是否包含狀态,Widgets 可以分為 stateful 和 stateless widget,對應的類是 StatefulWidget 和 StatelessWidget

對于有些 Widgets 來說,比如 icon 或者Label,它裡面本身就不需要狀态,這些 Widgets 就是 StatelessWidget

但是如果有些 Widgets 中的某些内容可能需要根據使用者或者其他原因來動态變化,則就需要使用 StatefulWidget

之前提到了 Widgets 是不可變的,StatefulWidget 中的可變資料是存放在對應的 State 中的,是以 StatefulWidgets 本身并沒有 build 方法,所有使用者界面都是通過 State 對象來建構的

當 State 發生變化的時候,需要調用 setState() 方法來通知 flutter 架構來調用 State 的 build 方法,進而将變化回報到使用者界面中

至此,我們今天關于 Flutter 架構 中的 Widgets 特性與知識點就介紹到這裡了;希望以上的内容能夠對大家有所幫助,關于 Flutter 的相關技術問題,我們還要去好好的學習剖析;是以我把工作中遇到的 Flutter 元件開源庫相關問題,以及對網上大部分的資料的收集和整理,最終整合出了一份 《Flutter 進階開發學習筆記》

有需要這份學習筆記的朋友,可以 私信 發送 “筆記” 即可 免費擷取 希望大家通過閱讀這份學習筆記,能夠查漏補缺;早日精通 Flutter

内容展示如下:

Dart 文法基礎

  • Dart 文法詳解
  • 編譯原理
  • Dart 語言基礎詳解(變量、内置類型、函數、操作符、流程控制語句)
  • Flutter(Dart)基礎——類的詳解
  • Dart 初始化清單
  • Dart 的構造方法及屬性(setter/getter)
  • Dart 構造方法
  • Dart 的工廠構造方法
  • Dart 之 Mixin 詳解
Flutter 跨平台架構中的 Widgets,你了解多少?

Dart 文法進階

  • Exception 類型
  • Error 類型
  • 異常抛出
  • 異常捕獲
  • 泛型
  • 異步
Flutter 跨平台架構中的 Widgets,你了解多少?

完整版 Flutter 進階開發學習筆記擷取方式: 私信發送 “筆記”即可 免費擷取

Flutter 3.0 之 UI

  • 清單和網格視圖 Widget
  • 布局 Widget
  • AbsListView 常用屬性和相關方法
  • 常用擴充卡介紹與使用
  • ListView 詳細介紹與使用
  • GridView 詳解與應用
  • GridView 主要使用方法
  • GridView 使用 Demo
  • 布局 Widget
Flutter 跨平台架構中的 Widgets,你了解多少?

Flutter 學習筆記目錄:

Flutter 跨平台架構中的 Widgets,你了解多少?

文章篇幅有限,資料就不做完全展示了;有需要這份 Flutter 進階開發學習筆記 的朋友: 私信 發送 “筆記” 即可 免費擷取

對于程式員來說,要學習的知識内容、技術有太多太多,要想不被環境淘汰就隻有不斷提升自己,從來都是我們去适應環境,而不是環境來适應我們

技術是無止境的,你需要對自己送出的每一行代碼、使用的每一個工具負責,不斷挖掘其底層原理,才能使自己的技術升華到更高的層面

最後祝各位開發者早日精通 Flutter ,攀登上更高的高峰