保羅的學習筆記

Day 18 - 事不關己,高高”掛“起

在開發 Flutter 的過程中,我們常常會使用到各式各樣的 Controller,從 AnimationController、TabController、TextEditingController …等。在使用這些 Controller 時,我們通常需要搭配使用 StatefulWidget 使用,避免畫面重 build 時,遺失當下的狀態。

Article image

在上面的例子中,我們使用 AnimationController 來幫助我們實現動畫,Controller 中會保存動畫當前的進度,並透過 AnimatedBuilder 即時更新動畫。

Controller 們的樣板程式碼

在上面的例子中,我們在 initState 與 dispose 中處理 controller 生命週期的開始與終結。當我們每次需要這些 Controller 時,我們都得初始化與終止 Controller,這些程式碼不斷的重複在每個需要 Controller 的場景。

dart
@override
void initState() {
  super.initState();
  // init controller
}

@override
void dispose() {
  // dispose controller
  super.dispose();
}

為了解決這些煩人的初始與終止問題,我們可以嘗試使用 flutter_hook 套件。

使用 Hook

當我們引入 flutter_hook 後,讓 Widget 繼承 HookWidget,我們就能在 build 方法中,直接使用 useAnimationController 取得 Controller 並使用,無需擔心 controller 的初始化與終止。

Article image

透過 Hook 讓套件幫助我們管理 controller 的生命週期,開發上只要專注於如何與 controller 互動即可。能簡化程式碼,讓程式碼更加簡潔,畢竟維護的程式碼越少,我們的工作就越輕鬆。

各式 useController

在 flutter_hook 中,除了 useAnimationController 之外,還有其他 Controller 可以使用,例如:當我們想使用 TabBar 與 TabBarView 時,少不了要使用 useTabController 來連動這兩個 Widget。

Article image

還有 useState

除此之外,由於 flutter_hook 的設計概念借鑒了 React Hook,所以我們也能在 flutter_hook 中找到像是 useState、useEffect 等 API。當我們使用了 flutter_hook 時,會發現由於我們繼承了 HookWidget,而不是 StatefulWidget,此時就需要改用 useState 來管理狀態了。

Article image

在上面的例子中,我們就把經典的 counter 範例,改用 flutter_hook 實現,在 useState 放入 counter 的初始值,當按下 + 按鈕後,數字就會不停的往上加。即時 build 方法不斷被執行,也能 counter 的狀態也不會被重設。

利用 Mixin 抽取共用

Mixin 除了能讓我們共用方法之外,也能共用繼承而來的方法。在下面的例子中,我們有一個 HpPrinter 繼承了 Printer 並使用了 PrinterMixin,當我們呼叫 printDoc 時,程式會先呼叫 PrinterMixin 中的 printDoc,然後才呼叫 HpPrinter 中的 printDoc。

Article image

了解 Mixin 的運作流程之後,我們就能使用同樣的方式來抽取一個控制 Controller 生命週期的 Mixin 了。在下面就讓我們修改 TabController 的例子,改成使用客製的 Mixin,讓 Mixin 來控制 controller 的生命週期。

Article image

結論

如果熟悉 React Hook 的讀者,想入門 Flutter 的話,在了解了 Flutter 基本概念之後,可以考慮使用 flutter_hook 來幫助開發。透過 useState、useController …等 API,簡化程式碼的寫法,讓程式碼更好讀易懂。

— 全文完 —

如果這篇對你有幫助,可以分享給朋友,或追蹤後續更新。我在 Threads 也會貼一些零碎想法。