【Flutter 元件集錄】TickerMode| 8月更文挑戰

張風捷特烈發表於2021-08-12
前言:

這是我參與8月更文挑戰的第 12 天,活動詳情檢視:8月更文挑戰。為應掘金的八月更文挑戰,我準備在本月挑選 31 個以前沒有介紹過的元件,進行全面分析和屬性介紹。這些文章將來會作為 Flutter 元件集錄 的重要素材。希望可以堅持下去,你的支援將是我最大的動力~

本系列元件文章列表
1.NotificationListener2.Dismissible3.Switch
4.Scrollbar5.ClipPath6.CupertinoActivityIndicator
7.Opacity8.FadeTransition9. AnimatedOpacity
10. FadeInImage11. Offstage12. TickerMode[本文]

一、認識 TickerMode 元件

可能絕大多數的人都沒聽說過這個元件,更沒用過。我們都知道 Ticker 是動畫控制器的底層驅動力,TickerMode 元件可以禁用/啟用子樹下所有的 Ticker ,也就是說它可以讓子樹的所有動畫無效或生效。我們可以通過動畫控制器來主動控制動畫的開啟或停止,那 TickerMode 元件的價值何在,它又是如何實現控制子樹所有的動畫呢?帶著這些問題,我們今天就來詳細分析一下 TickerMode 元件。


1.TickerMode 基本資訊

下面是 TickerMode 元件類的定義構造方法,可以看出它繼承自 StatelessWidget。例項化時必須傳入布林型的 enabledchild 元件。


2. TickerMode 的使用

下面通過一個案例測試一下 TickerMode 元件,如下 buildTestContent 方法構建的是下面的三個元件,被TickerMode 包裹。buildOutSwitch 是上面的Switch開關,它在 TickerMode 元件之外。

可見,當上面的Switch開關開啟 _disabletrue 時,TickerModeenabledfalse 。此時下面的兩個 loading 元件就停止了運動。從這可以看出,我們並沒有對兩個 loading 元件的動畫控制器執行任何操作,也沒有改變元件屬性進行重建。就可以直接禁用/啟用它們的動畫,是不是非常神奇。像這樣可以隨意插拔,幾乎沒有任何耦合性,卻能完成某個功能的元件,可以增加使用的靈活性。

@override
Widget build(BuildContext context) {
  return Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          buildOutSwitch(),
          TickerMode( //<--- 使用 TickerMode 
              enabled: !_disable,
              child: buildTestContent()),
        ],
      );
}

Widget buildOutSwitch() => Wrap(
          alignment: WrapAlignment.center,
          crossAxisAlignment: WrapCrossAlignment.center,
          children:[
            Text('TickerMode外的Switch:'),
            Switch(
            value: _disable,
            onChanged: _onChanged,
          )] ,
        );

Widget buildTestContent() => Wrap(
    alignment: WrapAlignment.center,
    crossAxisAlignment: WrapCrossAlignment.center,
    spacing: 20,
    children: [
      Switch(
        value: _disable,
        onChanged: _onChanged,
      ),
      CupertinoActivityIndicator(),
      CircularProgressIndicator(),
    ],
  );
複製程式碼

可能你會疑惑,我為什麼要在測試案例的下面一排放一個 Switch ?這樣可以更好地說明 TickerMode 的作用範圍。如下,點選下面的 Switch ,同樣也會切換 _disable 的狀態,可以看出由於下排的 Switch 上層的 TickerMode 被設為 disable:true,動畫被禁用了。對比兩個 Switch 的表現,你就能明白 TickerMode 的作用範圍是在子樹中。


二、 TickerMode 的原始碼實現

1. TickerMode 原始碼分析

TickerMode 元件的原始碼非常簡單,主要就是三個處理,分別是 構造方法build 構造、通過 of 靜態方法檢視 enabled 的值。其中 build 方法返回的是 _EffectiveTickerMode , of 靜態方法查通過 dependOnInheritedWidgetOfExactType 來查詢上級的 _EffectiveTickerMode 元件。那麼用腳指頭都能想出來 _EffectiveTickerMode 一定是一個 InheritedWidget ,且持有 enabled 資料。


2._EffectiveTickerMode 原始碼分析

果不其然,_EffectiveTickerMode 繼承自 InheritedWidget,並持有 enabled 資料。這樣該資料就可以在子樹中共享。這樣看來,動畫的體系中,應該會通過上下文獲取這個值,對 Trick 進行處理。如果你也就看完 《Flutter 動畫探索 - 流光幻影》,那麼這裡應該就能銜接上了。


3. TickerMode 控制動畫的原理

我們在使用動畫時,都會使用 SingleTickerProviderStateMixinTickerProviderStateMixin 來建立 動畫控制器《Flutter 動畫探索 - 流光幻影》的第 16 篇介紹了 TickerTickerProvider 的原始碼。

比如在 SingleTickerProviderStateMixin 中的一個不起眼的地方,有著一句不起眼的程式碼,這就是 TickerMode 控制動畫的原理 。不知道有多少人能說清 didChangeDependencies 的用途和回撥的時機,又有的多少人整天吵著這個狀態管理框架,那個路由管理工具。連最基本的乘法口訣都背不好,就去學奧數?

TickerProviderStateMixin 中也是類似,通過 TickerMode.of 獲取上層的值,來更新 Tickermuted 屬性。

很多看似毫不起眼的東西,都是至關重要的存在,也許某一處小細節,就可以讓你豁然開朗。從這裡也能看出 TickerMode 只會對 SingleTickerProviderStateMixinTickerProviderStateMixin 生效。也就是說,如果你是自己建立的 Ticker ,並且沒有在 didChangeDependencies 回撥中進行處理,那麼 TickerMode 就管不住這個 Ticker 。那TickerMode 的使用方式到這裡就介紹完畢,那本文到這裡就結束了,謝謝觀看,明天見~

相關文章