Flutter深入淺出元件篇---MaterialApp

Jimi發表於2021-08-21

Flutter整體結構圖

Flutter Framework

  • Foundation、Animation、Painting、Gestures被合成了一個Dart UI層,對應的是Flutter中 dart:ui 包,是Flutter引擎暴露的底層UI庫,主要提供動畫、手勢、繪製能力。
  • Rendering層是一個抽象佈局層,依賴於Dart UI層,Rendering層會構建一個UI樹、當UI樹有變化時,會計算出有變化的部分,然後更新UI樹,最終繪製在螢幕上
  • Widgets層是Flutter提供的一套基礎元件庫
  • Material、Cupertino是Flutter提供了兩種視覺風格的元件庫(Android、iOS)

Flutter Engine

這是一個純C++實現的SDK,主要執行相關的渲染、執行緒管理、平臺事件等操作。其中包括了Skia引擎、Dart執行時、文字排版引擎等。在呼叫dart:ui庫是,其實最終會走到Engine層,實現真正的繪製邏輯.

Flutter Embedder

提供四個Task Runner,將引擎一直到平臺中間層程式碼的渲染設定、原生外掛、打包、執行緒管理、時間迴圈、互動操作等。

  • UI Runner 負責繫結渲染相關操作
  • GPU Runner 使用者執行GPU指令
  • iOS Runner 處理圖片資料、為GPU做準備的
  • Platform Runner 所有介面呼叫都使用該介面

示例程式碼

本文中很多效果都沒有截圖,可下載原始碼執行專案 原始碼地址,或者通過視訊教程檢視 視訊教程地址

Material介紹

Material 元件(MDC)幫助開發者實現 Material Design。MDC 由谷歌團隊的工程師和 UX 設計師創造,為 Android、iOS、Web 和 Flutter 提供很多美觀實用的 UI 元件。

MaterialApp介紹

MaterialApp 包含了許多的 Widget ,這些 Widget 通常是實現 Material Design 的應用程式所必須要的,包含的 Widget 可以在 Material Components widgets 中檢視所有。 瞭解基本的概念,接下來我們詳細看一下 MaterialApp 具體怎麼使用。

Material屬性和說明

總共33個屬性

欄位屬性描述
navigatorKeyGlobalKey導航鍵
scaffoldMessengerKeyGlobalKey腳手架鍵
homeWidget主頁,應用開啟時顯示的頁面
routesMap<String, WidgetBuilder>應用程式頂級路由表
initialRouteString如果構建了導航器,則會顯示第一個路由的名稱
onGenerateRouteRouteFactory路由管理攔截器
onGenerateInitialRoutesInitialRouteListFactory生成初始化路由
onUnknownRouteRouteFactory當onGenerateRoute無法生成路由時呼叫
navigatorObserversList建立導航器的觀察者列表
builderTransitionBuilder在導航器上面插入小部件
titleString程式切換時顯示的標題
onGenerateTitleGenerateAppTitle程式切換時生成標題字串
colorColor程式切換時應用圖示背景顏色(僅安卓有效)
themeThemeData主題顏色
darkThemeThemeData暗黑模式主題顏色
highContrastThemeThemeData系統請求“高對比度”使用的主題
highContrastDarkThemeThemeData系統請求“高對比度”暗黑模式下使用的主題顏色
themeModeThemeMode使用哪種模式的主題(預設跟隨系統)
localeLocale初始區域設定
localizationsDelegatesIterable<LocalizationsDelegate>本地化代理
localeListResolutionCallbackLocaleListResolutionCallback失敗或未提供裝置的語言環境
localeResolutionCallbackLocaleResolutionCallback負責計算語言環境
supportedLocalesIterable本地化地區列表
debugShowMaterialGridbool繪製基線網格疊加層(僅debug模式)
showPerformanceOverlaybool顯示效能疊加
checkerboardRasterCacheImagesbool開啟柵格快取影像的棋盤格。
checkerboardOffscreenLayersbool開啟渲染到螢幕外點陣圖的層的棋盤格。
showSemanticsDebuggerbool開啟顯示可訪問性資訊的疊加層
debugShowCheckedModeBannerbool除錯顯示檢查模式橫幅
shortcutsMap<LogicalKeySet, Intent>應用程式意圖的鍵盤快捷鍵的預設對映。
actionsMap<Type, Action>包含和定義使用者操作的對映
restorationScopeIdString應用程式狀態恢復的識別符號
scrollBehaviorScrollBehavior可滾動小部件的行為方式

建構函式

建立一個MaterialApp

MaterialApp(...)

建立一個使用 Router 而不是 Navigator 的 MaterialApp

MaterialApp.router(...)

屬性詳解

1、navigatorKey

navigatorKey 相當於 Navigator.of(context) ,如果應用程式想實現無 context 跳轉,那麼可以通過設定該key, 通過 navigatorKey.currentState.overlay.context 獲取全域性context。

使用方法

GlobalKey<NavigatorState> _navigatorKey = GlobalKey();

MaterialApp(
  navigatorKey: _navigatorKey,
);

複製程式碼

2、scaffoldMessengerKey

scaffoldMessengerKey 主要是管理後代的 Scaffolds,可以實現無 context 呼叫 snack bars

使用方法

GlobalKey<ScaffoldMessengerState> _scaffoldKey = GlobalKey();

MaterialApp(
  scaffoldMessengerKey: _scaffoldKey,
);

_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("show SnackBar")));

複製程式碼

3、home

程式進入後的第一個介面,傳入一個 Widget

使用方法
...
MaterialApp(
  home: Scaffold(...),
);
...
複製程式碼

4、routes

生成路由表,以鍵值對形式傳入 key 為路由名字, value 為對應的Widget

使用方法
MaterialApp(
  routes: {
    "/home": (_) => Home(),
    "/my": (_) => My()
    //....
  },
);
複製程式碼

5、initialRoute

初始路由,如果設定了該引數並且在 routes 找到了對應的key,將會展示對應的 Widget ,否則展示 home

使用方法
 MaterialApp(
   routes: {
     "/home": (_) => Home(),
     "/my": (_) => My()
   },
   initialRoute: "/home",
 )
複製程式碼

6、onGenerateRoute

當跳轉路由時,如果在 routes 找不到對應的 key ,會執行該回撥,會呼叫會返回一個 RouteSettings ,該物件中有 name 路由名稱、 arguments 路由引數。

使用方法
 MaterialApp(
   routes: {
     "/home": (_) => Home(),
     "/my": (_) => My()
     },
   initialRoute: "/home",
   onGenerateRoute: (setting) {
     // 這裡可以做進一步的邏輯處理
     return MaterialPageRoute(builder: (_) => Home());
   },
)
複製程式碼

7、onGenerateInitialRoutes

如果提供了 initialRoute ,則用於生成初始路由的路由生成器回撥,如果未設定此屬性,則底層 Navigator.onGenerateInitialRoutes 將預設為 Navigator.defaultGenerateInitialRoutes

使用方法
MaterialApp(
  initialRoute: "/home",
  onGenerateInitialRoutes: (initialRoute) {
    return [
      MaterialPageRoute(builder: (_) => Home()),
      MaterialPageRoute(builder: (_) => My()),
    ];
  }
 )
複製程式碼

8、onUnknownRoute

效果和 onGenerateRoute 一樣,只是先走 onGenerateRoute ,如果無法生成路由時則在呼叫 onUnknownRoute

使用方法
MaterialApp(
   routes: {
     "/home": (_) => Home(),
     "/my": (_) => My()
     },
   initialRoute: "/home",
   onGenerateRoute: (setting) {
     return null;
   },
   onUnknownRoute: (setting) {
     return MaterialPageRoute(builder: (_) => Home());
   },
)
複製程式碼

9、navigatorObservers

路由監聽器,主要是就是監聽頁面路由堆疊的變化,當頁面進行 push pop remove replace 等操作時會進行監聽。

使用方法
MaterialApp(
 	navigatorObservers: [
    MyObserver()
  ],
)
  
 class MyObserver extends NavigatorObserver {
  @override
  void didPush(Route route, Route previousRoute) {
    print(route);
    print(previousRoute);
    super.didPush(route, previousRoute);
  }
}
複製程式碼

10、builder

當構建 Widget 前呼叫,主要用於字型大小、主題顏色等配置

使用方法
MaterialApp(
   routes: {
     "/home": (_) => Home(),
     "/my": (_) => My()
     },
   initialRoute: "/home",
   onGenerateRoute: (setting) {
     return null;
   },
   onUnknownRoute: (setting) {
     return MaterialPageRoute(builder: (_) => Home());
   },
 	 builder: (_, child) {
     return Scaffold(appBar: AppBar(title: Text("build")), body: child,);
   },
)
複製程式碼

11、title

Android:工作管理員的程式快照之上 IOS: 程式切換管理器中

使用方法
 MaterialApp(
   title: 'Flutter應用',
 );
複製程式碼

12、onGenerateTitle

如果非空,則呼叫此回撥函式以生成應用程式的標題字串,否則會使用 title 。每次重建頁面是該方法就會回撥執行。

使用方法
MaterialApp(
   title: 'Flutter應用',
   onGenerateTitle: (_) {
     return "我的天";
   },
 );
複製程式碼

13、color

設定該值的在程式切換時應用圖示的背景顏色,當應用圖示為透明時。

使用方法
MaterialApp(
  color: Colors.blue,
)
複製程式碼

14、theme

如果指定了 darkTheme ,那麼用於提供使用者介面的深色版本。如果提供了 darkThemethemeMode 將控制將使用哪個主題。預設值是 ThemeData.light() 應用程式的主題顏色

使用方法
MaterialApp(
  theme: ThemeData(
    // 主要顏色
    primaryColor: Colors.red
  ),
)
複製程式碼

15、darkTheme

應用程式深色主題顏色

使用方法
MaterialApp(
  theme: ThemeData(
    // 主要顏色
    primaryColor: Colors.red
  ),
)
複製程式碼

16、highContrastTheme

當系統請求“高對比度”時使用的 ThemeData ,當該值為空時會用 theme 應用該主題

使用方法
MaterialApp(
  highContrastTheme: ThemeData(
    primaryColor: Colors.pink
  ),
)
複製程式碼

17、highContrastDarkTheme

當系統再暗黑模式下請求“高對比度”時使用的 ThemeData ,當該值為空時會用 darkTheme 應用該主題。

使用方法
MaterialApp(
  highContrastDarkTheme: ThemeData(
    primaryColor: Colors.green
  ),
)
複製程式碼

18、themeMode

白天模式和暗黑模式模式切換,預設值為 ThemeMode.system

使用方法
MaterialApp(
  themeMode: ThemeMode.dark
)
複製程式碼

19、locale

主要用於語言切換時,如果為 null 時使用系統區域

使用方法
MaterialApp(
  locale: Locale('zh', 'CN') // 中文簡體
)
複製程式碼

20、localizationsDelegates

本地化委託

使用方法
MaterialApp(
  locale: Locale('zh', 'CN') // 中文簡體
  localizationsDelegates: [
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
  ],
)
複製程式碼

21、supportedLocales

當前應用支援的 Locale 列表

使用方法
MaterialApp(
  locale: Locale('zh', 'CN'), // 中文簡體
  supportedLocales: [
    Locale('en', 'US'), //美國英語
    Locale("zh", 'CN'), //中文簡體
  ]
)
複製程式碼

22、localeListResolutionCallback

監聽系統語言切換事件,一些安卓系統特性,可設定多語言列表,預設以第一個列表為預設語言

使用方法
MaterialApp(
  locale: Locale('zh', 'CN'), // 中文簡體
  supportedLocales: [
    Locale('en', 'US'), //美國英語
    Locale("zh", 'CN'), //中文簡體
  ],
  localeListResolutionCallback: (List<Locale> locales, Iterable<Locale> supportedLocales) {
    // 系統切換語言時呼叫
    return Locale("zh", 'CN');
  },
)
複製程式碼

23、localeResolutionCallback

監聽系統語言切換事件

使用方法
MaterialApp(
  locale: Locale('zh', 'CN'), // 中文簡體
  supportedLocales: [
    Locale('en', 'US'), //美國英語
    Locale("zh", 'CN'), //中文簡體
  ],
  localeResolutionCallback: (Locale locale, Iterable<Locale> supportedLocales) {
    return Locale("zh", 'CN');
  },
)
複製程式碼

24、debugShowMaterialGrid

debug 模式下展示基線網格

使用方法
MaterialApp(
  debugShowMaterialGrid: true
)
複製程式碼

25、showPerformanceOverlay

顯示效能疊加,開啟此模式主要用於效能測試

使用方法
MaterialApp(
  showPerformanceOverlay: true
)
複製程式碼

26、checkerboardRasterCacheImages

開啟柵格快取影像的棋盤格

使用方法
MaterialApp(
  checkerboardRasterCacheImages: true
)
複製程式碼

27、checkerboardOffscreenLayers

開啟渲染到螢幕外點陣圖的層的棋盤格

使用方法
MaterialApp(
  checkerboardOffscreenLayers: true
)
複製程式碼

28、showSemanticsDebugger

開啟顯示可訪問性資訊的疊加層,展示元件之間的關係、佔位大小

使用方法
MaterialApp(
  showSemanticsDebugger: true
)
複製程式碼

29、debugShowCheckedModeBanner

除錯顯示檢查模式橫幅

使用方法
MaterialApp(
  debugShowCheckedModeBanner: false
)
複製程式碼

30、shortcuts以及actions

shortcutsactions 是將物理鍵盤事件繫結到使用者介面中的操作。 比如,要在您的應用程式中定義鍵盤快捷鍵,這裡不做過多的描述,後面我會專門拿一個專題來講解。

31、restorationScopeId

定義一個應用程式狀態恢復的識別符號,提供識別符號會將 RootRestorationScope 插入 widget 層次結構,從而為後代 widget 啟用狀態恢復。還可以通過識別符號使 WidgetsApp 構建的導航器恢復其狀態(即恢復活動路由的歷史堆疊),由於這裡涉及的內容較多,後面會專門拿一個專題來講解。

32、scrollBehavior

統一滾動行為設定,設定後子元件將返回對應的滾動行為

使用方法
MaterialApp(
  scrollBehavior: ScrollBehaviorModified()
)
  
class ScrollBehaviorModified extends ScrollBehavior {
  const ScrollBehaviorModified();
  @override
  ScrollPhysics getScrollPhysics(BuildContext context) {
    switch (getPlatform(context)) {
      case TargetPlatform.iOS:
      case TargetPlatform.macOS:
      case TargetPlatform.android:
        return const BouncingScrollPhysics();
      case TargetPlatform.fuchsia:
      case TargetPlatform.linux:
      case TargetPlatform.windows:
        return const ClampingScrollPhysics();
    }
    return null;
  }
}

複製程式碼

相關文章