Flutter MaterialApp 裡到底藏了什麼?

What's in Flutter MaterialApp?

Posted by Bobson Lin on Monday, March 4, 2019

前言

一開始創建 Flutter App 它會自己有個 Counter 的範例,到後續自己寫了很多範例跟專案正在開發; 才發現光是一個 MaterialApp 水就很深了,決定努力來看一下文檔以及源碼整理並理解。

MaterialApp

An application that uses material design.

A convenience widget that wraps a number of widgets that are commonly required for material design applications. It builds upon a WidgetsApp by adding material-design specific functionality, such as AnimatedTheme and GridPaper.

以上是官方文檔中前兩段敘述,概略的說 MaterialApp 是根據 Material Design 風格包裝了 WidgetsApp,例如 AnimatedTheme and GridPaper

MaterialAppWidgetsApp 都屬於 StatefulWidget

接下來看看 MaterialApp 所使用到的變數:

materialapp_variables

我把它分作四類:

  • [紅色] 跟頁面轉換有關 (Navigator, Route…)
  • [橘色] 跟多語言有關 (l10n, i18n)
  • [藍色] 與開發相關 (Debug, PerformanceOvelay…)
  • [其他] 與App本身相關 (設計主題, App名稱…)

文檔中花比較多篇文在 [紅色] 部份,所以這篇文章主要是深入研究 [紅色] 和 [其他]。
[橘色] 及 [藍色] 之後有研究再補充。

AnimatedTheme

Animated version of Theme which automatically transitions the colors, etc, over a given duration whenever the given theme changes.

AnimatedTheme 封裝了 Theme 增加了動畫的性質,可以從 DevTools 中看出它給了 ThemeDataTween 這個動畫期間,主要能體現於更換主題時之間的動畫效果。

animated_theme_in_devtools

最簡單的實驗,就是開發變換主題變數之後 Hot Restart,會產生短暫的動畫效果,這就是 AnimatedTheme 所影響的。

以下是在 MaterialAppState.build 中更改了 AnimatedTheme.duration:

animated_theme

GridPaper

GridPaper 主要用於 Material Design,可設定 MaterialAppState.debugShowMaterialGrid 為 true,開啟網格模式。

grid_paper

WidgetsApp

其實大部分 MaterialApp 的功能都在 WidgetsApp 裡就實現了,仔細看看 WidgetsApp 的文檔和源碼會發現,其實 MaterialApp 所使用到的變數,大部分都傳給 WidgetsApp 了。

MaterialApp 花了滿多篇幅在講這部份的,搭配源碼看可以知道他們做了很多事情。

首先,WidgetsApp.build 裡會自動創建一個 Navigator Widget 給當前的 App。
Navigator 所創建出來的 NavigatorState 中其中有一部份會管理 Route 物件堆疊(stack)。