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個屬性
欄位 | 屬性 | 描述 |
---|---|---|
navigatorKey | GlobalKey | 導航鍵 |
scaffoldMessengerKey | GlobalKey | 腳手架鍵 |
home | Widget | 主頁,應用開啟時顯示的頁面 |
routes | Map<String, WidgetBuilder> | 應用程式頂級路由表 |
initialRoute | String | 如果構建了導航器,則會顯示第一個路由的名稱 |
onGenerateRoute | RouteFactory | 路由管理攔截器 |
onGenerateInitialRoutes | InitialRouteListFactory | 生成初始化路由 |
onUnknownRoute | RouteFactory | 當onGenerateRoute無法生成路由時呼叫 |
navigatorObservers | List | 建立導航器的觀察者列表 |
builder | TransitionBuilder | 在導航器上面插入小部件 |
title | String | 程式切換時顯示的標題 |
onGenerateTitle | GenerateAppTitle | 程式切換時生成標題字串 |
color | Color | 程式切換時應用圖示背景顏色(僅安卓有效) |
theme | ThemeData | 主題顏色 |
darkTheme | ThemeData | 暗黑模式主題顏色 |
highContrastTheme | ThemeData | 系統請求“高對比度”使用的主題 |
highContrastDarkTheme | ThemeData | 系統請求“高對比度”暗黑模式下使用的主題顏色 |
themeMode | ThemeMode | 使用哪種模式的主題(預設跟隨系統) |
locale | Locale | 初始區域設定 |
localizationsDelegates | Iterable<LocalizationsDelegate> | 本地化代理 |
localeListResolutionCallback | LocaleListResolutionCallback | 失敗或未提供裝置的語言環境 |
localeResolutionCallback | LocaleResolutionCallback | 負責計算語言環境 |
supportedLocales | Iterable | 本地化地區列表 |
debugShowMaterialGrid | bool | 繪製基線網格疊加層(僅debug模式) |
showPerformanceOverlay | bool | 顯示效能疊加 |
checkerboardRasterCacheImages | bool | 開啟柵格快取影像的棋盤格。 |
checkerboardOffscreenLayers | bool | 開啟渲染到螢幕外點陣圖的層的棋盤格。 |
showSemanticsDebugger | bool | 開啟顯示可訪問性資訊的疊加層 |
debugShowCheckedModeBanner | bool | 除錯顯示檢查模式橫幅 |
shortcuts | Map<LogicalKeySet, Intent> | 應用程式意圖的鍵盤快捷鍵的預設對映。 |
actions | Map<Type, Action> | 包含和定義使用者操作的對映 |
restorationScopeId | String | 應用程式狀態恢復的識別符號 |
scrollBehavior | ScrollBehavior | 可滾動小部件的行為方式 |
建構函式
建立一個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
,那麼用於提供使用者介面的深色版本。如果提供了 darkTheme
, themeMode
將控制將使用哪個主題。預設值是 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
shortcuts
和 actions
是將物理鍵盤事件繫結到使用者介面中的操作。 比如,要在您的應用程式中定義鍵盤快捷鍵,這裡不做過多的描述,後面我會專門拿一個專題來講解。
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;
}
}
複製程式碼