Flutter深入浅出组件篇---MaterialApp

Flutter整体结构图

image

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<NavigatorState> 导航键
scaffoldMessengerKey GlobalKey<ScaffoldMessengerState> 脚手架键
home Widget 主页,应用打开时显示的页面
routes Map<String, WidgetBuilder> 应用程序顶级路由表
initialRoute String 如果构建了导航器,则会显示第一个路由的名称
onGenerateRoute RouteFactory 路由管理拦截器
onGenerateInitialRoutes InitialRouteListFactory 生成初始化路由
onUnknownRoute RouteFactory 当onGenerateRoute无法生成路由时调用
navigatorObservers List<NavigatorObserver> 创建导航器的观察者列表
builder TransitionBuilder 在导航器上面插入小部件
title String 程序切换时显示的标题
onGenerateTitle GenerateAppTitle 程序切换时生成标题字符串
color Color 程序切换时应用图标背景颜色(仅安卓有效)
theme ThemeData 主题颜色
darkTheme ThemeData 暗黑模式主题颜色
highContrastTheme ThemeData 系统请求“高对比度”使用的主题
highContrastDarkTheme ThemeData 系统请求“高对比度”暗黑模式下使用的主题颜色
themeMode ThemeMode 使用哪种模式的主题(默认跟随系统)
locale Locale 初始区域设置
localizationsDelegates Iterable<LocalizationsDelegate<dynamic>> 本地化代理
localeListResolutionCallback LocaleListResolutionCallback 失败或未提供设备的语言环境
localeResolutionCallback LocaleResolutionCallback 负责计算语言环境
supportedLocales Iterable<Locale> 本地化地区列表
debugShowMaterialGrid bool 绘制基线网格叠加层(仅debug模式)
showPerformanceOverlay bool 显示性能叠加
checkerboardRasterCacheImages bool 打开栅格缓存图像的棋盘格。
checkerboardOffscreenLayers bool 打开渲染到屏幕外位图的层的棋盘格。
showSemanticsDebugger bool 打开显示可访问性信息的叠加层
debugShowCheckedModeBanner bool 调试显示检查模式横幅
shortcuts Map<LogicalKeySet, Intent> 应用程序意图的键盘快捷键的默认映射。
actions Map<Type, Action<Intent>> 包含和定义用户操作的映射
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 ,那么用于提供用户界面的深色版本。如果提供了 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;
  }
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容