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

Flutter整體結(jié)構(gòu)圖

image

Flutter Framework

  • Foundation那婉、Animation、Painting党瓮、Gestures被合成了一個(gè)Dart UI層详炬,對(duì)應(yīng)的是Flutter中 dart:ui 包,是Flutter引擎暴露的底層UI庫(kù)寞奸,主要提供動(dòng)畫呛谜、手勢(shì)、繪制能力枪萄。
  • Rendering層是一個(gè)抽象布局層隐岛,依賴于Dart UI層,Rendering層會(huì)構(gòu)建一個(gè)UI樹瓷翻、當(dāng)UI樹有變化時(shí)聚凹,會(huì)計(jì)算出有變化的部分割坠,然后更新UI樹,最終繪制在屏幕上
  • Widgets層是Flutter提供的一套基礎(chǔ)組件庫(kù)
  • Material妒牙、Cupertino是Flutter提供了兩種視覺(jué)風(fēng)格的組件庫(kù)(Android彼哼、iOS)

Flutter Engine

這是一個(gè)純C++實(shí)現(xiàn)的SDK,主要執(zhí)行相關(guān)的渲染单旁、線程管理沪羔、平臺(tái)事件等操作。其中包括了Skia引擎象浑、Dart運(yùn)行時(shí)榛瓮、文字排版引擎等。在調(diào)用dart:ui庫(kù)是坊谁,其實(shí)最終會(huì)走到Engine層矮嫉,實(shí)現(xiàn)真正的繪制邏輯.

Flutter Embedder

提供四個(gè)Task Runner,將引擎一直到平臺(tái)中間層代碼的渲染設(shè)置蚪拦、原生插件杖剪、打包、線程管理驰贷、時(shí)間循環(huán)盛嘿、交互操作等。

  • UI Runner 負(fù)責(zé)綁定渲染相關(guān)操作
  • GPU Runner 用戶執(zhí)行GPU指令
  • iOS Runner 處理圖片數(shù)據(jù)括袒、為GPU做準(zhǔn)備的
  • Platform Runner 所有接口調(diào)用都使用該接口

示例代碼

本文中很多效果都沒(méi)有截圖次兆,可下載源代碼運(yùn)行項(xiàng)目 源代碼地址,或者通過(guò)視頻教程查看 視頻教程地址

Material介紹

Material 組件(MDC)幫助開(kāi)發(fā)者實(shí)現(xiàn) Material Design锹锰。MDC 由谷歌團(tuán)隊(duì)的工程師和 UX 設(shè)計(jì)師創(chuàng)造芥炭,為 Android、iOS恃慧、Web 和 Flutter 提供很多美觀實(shí)用的 UI 組件园蝠。

MaterialApp介紹

MaterialApp 包含了許多的 Widget ,這些 Widget 通常是實(shí)現(xiàn) Material Design 的應(yīng)用程序所必須要的痢士,包含的 Widget 可以在 Material Components widgets 中查看所有彪薛。
了解基本的概念,接下來(lái)我們?cè)敿?xì)看一下 MaterialApp 具體怎么使用良瞧。

Material屬性和說(shuō)明

總共33個(gè)屬性

字段 屬性 描述
navigatorKey GlobalKey<NavigatorState> 導(dǎo)航鍵
scaffoldMessengerKey GlobalKey<ScaffoldMessengerState> 腳手架鍵
home Widget 主頁(yè)陪汽,應(yīng)用打開(kāi)時(shí)顯示的頁(yè)面
routes Map<String, WidgetBuilder> 應(yīng)用程序頂級(jí)路由表
initialRoute String 如果構(gòu)建了導(dǎo)航器,則會(huì)顯示第一個(gè)路由的名稱
onGenerateRoute RouteFactory 路由管理攔截器
onGenerateInitialRoutes InitialRouteListFactory 生成初始化路由
onUnknownRoute RouteFactory 當(dāng)onGenerateRoute無(wú)法生成路由時(shí)調(diào)用
navigatorObservers List<NavigatorObserver> 創(chuàng)建導(dǎo)航器的觀察者列表
builder TransitionBuilder 在導(dǎo)航器上面插入小部件
title String 程序切換時(shí)顯示的標(biāo)題
onGenerateTitle GenerateAppTitle 程序切換時(shí)生成標(biāo)題字符串
color Color 程序切換時(shí)應(yīng)用圖標(biāo)背景顏色(僅安卓有效)
theme ThemeData 主題顏色
darkTheme ThemeData 暗黑模式主題顏色
highContrastTheme ThemeData 系統(tǒng)請(qǐng)求“高對(duì)比度”使用的主題
highContrastDarkTheme ThemeData 系統(tǒng)請(qǐng)求“高對(duì)比度”暗黑模式下使用的主題顏色
themeMode ThemeMode 使用哪種模式的主題(默認(rèn)跟隨系統(tǒng))
locale Locale 初始區(qū)域設(shè)置
localizationsDelegates Iterable<LocalizationsDelegate<dynamic>> 本地化代理
localeListResolutionCallback LocaleListResolutionCallback 失敗或未提供設(shè)備的語(yǔ)言環(huán)境
localeResolutionCallback LocaleResolutionCallback 負(fù)責(zé)計(jì)算語(yǔ)言環(huán)境
supportedLocales Iterable<Locale> 本地化地區(qū)列表
debugShowMaterialGrid bool 繪制基線網(wǎng)格疊加層(僅debug模式)
showPerformanceOverlay bool 顯示性能疊加
checkerboardRasterCacheImages bool 打開(kāi)柵格緩存圖像的棋盤格褥蚯。
checkerboardOffscreenLayers bool 打開(kāi)渲染到屏幕外位圖的層的棋盤格挚冤。
showSemanticsDebugger bool 打開(kāi)顯示可訪問(wèn)性信息的疊加層
debugShowCheckedModeBanner bool 調(diào)試顯示檢查模式橫幅
shortcuts Map<LogicalKeySet, Intent> 應(yīng)用程序意圖的鍵盤快捷鍵的默認(rèn)映射。
actions Map<Type, Action<Intent>> 包含和定義用戶操作的映射
restorationScopeId String 應(yīng)用程序狀態(tài)恢復(fù)的標(biāo)識(shí)符
scrollBehavior ScrollBehavior 可滾動(dòng)小部件的行為方式

構(gòu)造函數(shù)

創(chuàng)建一個(gè)MaterialApp

MaterialApp(...)

創(chuàng)建一個(gè)使用 Router 而不是 Navigator 的 MaterialApp

MaterialApp.router(...)

屬性詳解

1赞庶、navigatorKey

navigatorKey 相當(dāng)于 Navigator.of(context) 训挡,如果應(yīng)用程序想實(shí)現(xiàn)無(wú) context 跳轉(zhuǎn)澳骤,那么可以通過(guò)設(shè)置該key, 通過(guò) navigatorKey.currentState.overlay.context 獲取全局context。

使用方法

GlobalKey<NavigatorState> _navigatorKey = GlobalKey();

MaterialApp(
  navigatorKey: _navigatorKey,
);

2澜薄、scaffoldMessengerKey

scaffoldMessengerKey 主要是管理后代的 Scaffolds为肮,可以實(shí)現(xiàn)無(wú) context 調(diào)用 snack bars

使用方法

GlobalKey<ScaffoldMessengerState> _scaffoldKey = GlobalKey();

MaterialApp(
  scaffoldMessengerKey: _scaffoldKey,
);

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

3、home

程序進(jìn)入后的第一個(gè)界面肤京,傳入一個(gè) Widget

使用方法
...
MaterialApp(
  home: Scaffold(...),
);
...

4颊艳、routes

生成路由表,以鍵值對(duì)形式傳入 key 為路由名字忘分, value 為對(duì)應(yīng)的Widget

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

5棋枕、initialRoute

初始路由,如果設(shè)置了該參數(shù)并且在 routes 找到了對(duì)應(yīng)的key妒峦,將會(huì)展示對(duì)應(yīng)的 Widget 重斑,否則展示 home

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

6、onGenerateRoute

當(dāng)跳轉(zhuǎn)路由時(shí)肯骇,如果在 routes 找不到對(duì)應(yīng)的 key 窥浪,會(huì)執(zhí)行該回調(diào),會(huì)調(diào)用會(huì)返回一個(gè) RouteSettings 笛丙,該對(duì)象中有 name 路由名稱漾脂、 arguments 路由參數(shù)。

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

7胚鸯、onGenerateInitialRoutes

如果提供了 initialRoute 符相,則用于生成初始路由的路由生成器回調(diào),如果未設(shè)置此屬性蠢琳,則底層 Navigator.onGenerateInitialRoutes 將默認(rèn)為 Navigator.defaultGenerateInitialRoutes

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

8镜豹、onUnknownRoute

效果和 onGenerateRoute 一樣傲须,只是先走 onGenerateRoute ,如果無(wú)法生成路由時(shí)則在調(diào)用 onUnknownRoute 趟脂。

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

9泰讽、navigatorObservers

路由監(jiān)聽(tīng)器,主要是就是監(jiān)聽(tīng)頁(yè)面路由堆棧的變化昔期,當(dāng)頁(yè)面進(jìn)行 push pop remove replace 等操作時(shí)會(huì)進(jìn)行監(jiān)聽(tīng)已卸。

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

10、builder

當(dāng)構(gòu)建 Widget 前調(diào)用硼一,主要用于字體大小累澡、主題顏色等配置

使用方法
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:任務(wù)管理器的程序快照之上
IOS: 程序切換管理器中

使用方法
 MaterialApp(
   title: 'Flutter應(yīng)用',
 );

12般贼、onGenerateTitle

如果非空愧哟,則調(diào)用此回調(diào)函數(shù)以生成應(yīng)用程序的標(biāo)題字符串奥吩,否則會(huì)使用 title 。每次重建頁(yè)面是該方法就會(huì)回調(diào)執(zhí)行蕊梧。

使用方法
MaterialApp(
   title: 'Flutter應(yīng)用',
   onGenerateTitle: (_) {
     return "我的天";
   },
 );

13霞赫、color

設(shè)置該值的在程序切換時(shí)應(yīng)用圖標(biāo)的背景顏色,當(dāng)應(yīng)用圖標(biāo)為透明時(shí)肥矢。

使用方法
MaterialApp(
  color: Colors.blue,
)

14端衰、theme

如果指定了 darkTheme ,那么用于提供用戶界面的深色版本甘改。如果提供了 darkTheme 旅东, themeMode 將控制將使用哪個(gè)主題。默認(rèn)值是 ThemeData.light()
應(yīng)用程序的主題顏色

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

15楼誓、darkTheme

應(yīng)用程序深色主題顏色

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

16玉锌、highContrastTheme

當(dāng)系統(tǒng)請(qǐng)求“高對(duì)比度”時(shí)使用的 ThemeData ,當(dāng)該值為空時(shí)會(huì)用 theme 應(yīng)用該主題

使用方法
MaterialApp(
  highContrastTheme: ThemeData(
    primaryColor: Colors.pink
  ),
)

17疟羹、highContrastDarkTheme

當(dāng)系統(tǒng)再暗黑模式下請(qǐng)求“高對(duì)比度”時(shí)使用的 ThemeData 主守,當(dāng)該值為空時(shí)會(huì)用 darkTheme 應(yīng)用該主題。

使用方法
MaterialApp(
  highContrastDarkTheme: ThemeData(
    primaryColor: Colors.green
  ),
)

18榄融、themeMode

白天模式和暗黑模式模式切換参淫,默認(rèn)值為 ThemeMode.system

使用方法
MaterialApp(
  themeMode: ThemeMode.dark
)

19、locale

主要用于語(yǔ)言切換時(shí)愧杯,如果為 null 時(shí)使用系統(tǒng)區(qū)域

使用方法
MaterialApp(
  locale: Locale('zh', 'CN') // 中文簡(jiǎn)體
)

20涎才、localizationsDelegates

本地化委托

使用方法
MaterialApp(
  locale: Locale('zh', 'CN') // 中文簡(jiǎn)體
  localizationsDelegates: [
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
  ],
)

21、supportedLocales

當(dāng)前應(yīng)用支持的 Locale 列表

使用方法
MaterialApp(
  locale: Locale('zh', 'CN'), // 中文簡(jiǎn)體
  supportedLocales: [
    Locale('en', 'US'), //美國(guó)英語(yǔ)
    Locale("zh", 'CN'), //中文簡(jiǎn)體
  ]
)

22力九、localeListResolutionCallback

監(jiān)聽(tīng)系統(tǒng)語(yǔ)言切換事件耍铜,一些安卓系統(tǒng)特性,可設(shè)置多語(yǔ)言列表跌前,默認(rèn)以第一個(gè)列表為默認(rèn)語(yǔ)言

使用方法
MaterialApp(
  locale: Locale('zh', 'CN'), // 中文簡(jiǎn)體
  supportedLocales: [
    Locale('en', 'US'), //美國(guó)英語(yǔ)
    Locale("zh", 'CN'), //中文簡(jiǎn)體
  ],
  localeListResolutionCallback: (List<Locale> locales, Iterable<Locale> supportedLocales) {
    // 系統(tǒng)切換語(yǔ)言時(shí)調(diào)用
    return Locale("zh", 'CN');
  },
)

23棕兼、localeResolutionCallback

監(jiān)聽(tīng)系統(tǒng)語(yǔ)言切換事件

使用方法
MaterialApp(
  locale: Locale('zh', 'CN'), // 中文簡(jiǎn)體
  supportedLocales: [
    Locale('en', 'US'), //美國(guó)英語(yǔ)
    Locale("zh", 'CN'), //中文簡(jiǎn)體
  ],
  localeResolutionCallback: (Locale locale, Iterable<Locale> supportedLocales) {
    return Locale("zh", 'CN');
  },
)

24、debugShowMaterialGrid

debug 模式下展示基線網(wǎng)格

使用方法
MaterialApp(
  debugShowMaterialGrid: true
)

25抵乓、showPerformanceOverlay

顯示性能疊加伴挚,開(kāi)啟此模式主要用于性能測(cè)試

使用方法
MaterialApp(
  showPerformanceOverlay: true
)

26、checkerboardRasterCacheImages

打開(kāi)柵格緩存圖像的棋盤格

使用方法
MaterialApp(
  checkerboardRasterCacheImages: true
)

27灾炭、checkerboardOffscreenLayers

打開(kāi)渲染到屏幕外位圖的層的棋盤格

使用方法
MaterialApp(
  checkerboardOffscreenLayers: true
)

28茎芋、showSemanticsDebugger

打開(kāi)顯示可訪問(wèn)性信息的疊加層,展示組件之間的關(guān)系蜈出、占位大小

使用方法
MaterialApp(
  showSemanticsDebugger: true
)

29田弥、debugShowCheckedModeBanner

調(diào)試顯示檢查模式橫幅

使用方法
MaterialApp(
  debugShowCheckedModeBanner: false
)

30、shortcuts以及actions

shortcutsactions 是將物理鍵盤事件綁定到用戶界面中的操作铡原。 比如皱蹦,要在您的應(yīng)用程序中定義鍵盤快捷鍵煤杀,這里不做過(guò)多的描述,后面我會(huì)專門拿一個(gè)專題來(lái)講解沪哺。

31沈自、restorationScopeId

定義一個(gè)應(yīng)用程序狀態(tài)恢復(fù)的標(biāo)識(shí)符,提供標(biāo)識(shí)符會(huì)將 RootRestorationScope 插入 widget 層次結(jié)構(gòu)辜妓,從而為后代 widget 啟用狀態(tài)恢復(fù)枯途。還可以通過(guò)標(biāo)識(shí)符使 WidgetsApp 構(gòu)建的導(dǎo)航器恢復(fù)其狀態(tài)(即恢復(fù)活動(dòng)路由的歷史堆棧),由于這里涉及的內(nèi)容較多籍滴,后面會(huì)專門拿一個(gè)專題來(lái)講解酪夷。

32、scrollBehavior

統(tǒng)一滾動(dòng)行為設(shè)置孽惰,設(shè)置后子組件將返回對(duì)應(yīng)的滾動(dòng)行為

使用方法
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;
  }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晚岭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子勋功,更是在濱河造成了極大的恐慌坦报,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狂鞋,死亡現(xiàn)場(chǎng)離奇詭異片择,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)骚揍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門字管,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人信不,你說(shuō)我怎么就攤上這事嘲叔。” “怎么了抽活?”我有些...
    開(kāi)封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵借跪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我酌壕,道長(zhǎng),這世上最難降的妖魔是什么歇由? 我笑而不...
    開(kāi)封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任卵牍,我火速辦了婚禮,結(jié)果婚禮上沦泌,老公的妹妹穿的比我還像新娘糊昙。我一直安慰自己,他們只是感情好谢谦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布释牺。 她就那樣靜靜地躺著萝衩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪没咙。 梳的紋絲不亂的頭發(fā)上猩谊,一...
    開(kāi)封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音祭刚,去河邊找鬼牌捷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛涡驮,可吹牛的內(nèi)容都是我干的暗甥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼捉捅,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼撤防!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起棒口,我...
    開(kāi)封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤寄月,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后陌凳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體剥懒,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年合敦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了初橘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡充岛,死狀恐怖保檐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情崔梗,我是刑警寧澤夜只,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蒜魄,受9級(jí)特大地震影響扔亥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谈为,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一旅挤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧伞鲫,春花似錦粘茄、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)儒搭。三九已至,卻和暖如春芙贫,著一層夾襖步出監(jiān)牢的瞬間搂鲫,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工屹培, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留默穴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓褪秀,卻偏偏與公主長(zhǎng)得像蓄诽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子媒吗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容