https://api.flutter.dev/flutter/material/MaterialApp-class.html
https://api.flutter.dev/flutter/material/ThemeData-class.html

MaterialApp 是一个方便的 Widget,它封装了应用程序实现 Material Design 所需要的一些 Widget。一般作为顶层 Widget 使用。

定义

  1. MaterialApp({
  2. Key key,
  3. this.navigatorKey,
  4. this.home, //App默认显示的页面
  5. this.routes = const <String, WidgetBuilder>{},
  6. this.initialRoute,
  7. this.onGenerateRoute,
  8. this.onGenerateInitialRoutes,
  9. this.onUnknownRoute,
  10. this.navigatorObservers = const <NavigatorObserver>[],
  11. this.builder,
  12. this.title = '',
  13. this.onGenerateTitle,
  14. this.color,
  15. this.theme,
  16. this.darkTheme,
  17. this.highContrastTheme,
  18. this.highContrastDarkTheme,
  19. this.themeMode = ThemeMode.system,
  20. this.locale,
  21. this.localizationsDelegates,
  22. this.localeListResolutionCallback,
  23. this.localeResolutionCallback,
  24. this.supportedLocales = const <Locale>[Locale('en', 'US')],
  25. this.debugShowMaterialGrid = false, //打开网格调试
  26. this.showPerformanceOverlay = false, //打开性能检测
  27. this.checkerboardRasterCacheImages = false,
  28. this.checkerboardOffscreenLayers = false,
  29. this.showSemanticsDebugger = false, //打开语义化调试
  30. this.debugShowCheckedModeBanner = true, //打开右上角debug图标
  31. this.shortcuts,
  32. this.actions,
  33. })

常用参数

home

App默认显示的页面

title

应用程序的描述,在Android上,在任务管理器的应用程序快照上面显示,在IOS上忽略此属性,IOS上任务管理器应用程序快照上面显示的是Info.plist文件中的CFBundleDisplayName。如果想根据区域显示不同的描述使用onGenerateTitle,用法如下:

  1. MaterialApp(
  2. title: 'APP 标题',
  3. onGenerateTitle: (context) {
  4. var local = Localizations.localeOf(context);
  5. if (local.languageCode == 'zh') {
  6. return 'APP 标题';
  7. }
  8. return 'App title';
  9. },
  10. ...
  11. )

routes、initialRoute、onGenerateRoute、onUnknownRoute

routesinitialRouteonGenerateRouteonUnknownRoute是和路由相关的4个属性,路由简单的理解就是页面,路由的管理通常是指页面的管理,比如跳转、返回等。

MaterialApp按照如下的规则匹配路由:

  1. 路由为/home不为null则使用home
  2. 使用routes指定的路由。
  3. 使用onGenerateRoute生成的路由,处理除homeroutes以外的路由。
  4. 如果上面都不匹配则调用onUnknownRoute

路由加载规则:

如果initialRoute 设置为 /,那么加载 HomePage 页面;
如果initialRoute设置为 /search,在routes中存在,所以加载routes中指定的路由,即SearchPage页面;
如果initialRoute设置为 /bag,此时routes中并不存在名称为 /bag 路由,调用onGenerateRoute;
如果onGenerateRoute返回路由页面,则加载此页面;
如果返回的是null,且 home参数 不为null,则加载home参数指定的页面;
如果home为null,则回调onUnknownRoute。

  1. MaterialApp(
  2. routes: {
  3. '/': (context) => HomePage(),
  4. '/search': (context) => SearchPage(),
  5. '/login': (context) => LoginPage(),
  6. },
  7. initialRoute: '/',
  8. home: Scaffold(
  9. appBar: AppBar(title: Text('标题')),
  10. ),
  11. onGenerateRoute: (RouteSettings routeSettings){
  12. if(routeSettings.name == 'search'){
  13. return MaterialPageRoute(builder: (context){
  14. return SearchPage();
  15. });
  16. }
  17. },
  18. onUnknownRoute: (RouteSettings routeSettings){
  19. return MaterialPageRoute(builder: (context){
  20. return ErrorPage();
  21. });
  22. },
  23. ...
  24. )

theme、darkTheme、themeMode

themedarkThemethemeMode是关于主题的参数,设置整个App的主题,包括颜色、字体、形状等。

示例:修改主题颜色为红色用法如下:

image.png

  1. MaterialApp(
  2. theme: ThemeData(
  3. primaryColor: Colors.red
  4. ),
  5. darkTheme: ThemeData(
  6. primaryColor: Colors.red
  7. ),
  8. themeMode: ThemeMode.dark,
  9. home: Scaffold(
  10. appBar: AppBar(title: Text('标题')),
  11. ),
  12. )

locale、localizationsDelegates等

localelocalizationsDelegateslocaleListResolutionCallbacklocaleResolutionCallbacksupportedLocales是区域设置和国际化相关的参数,如果App支持多国语言,那么就需要设置这些参数。

默认情况下,Flutter仅支持美国英语,如果想要添加其他语言支持则需要指定其他MaterialApp属性,并引入flutter_localizations 包,到2019年4月,flutter_localizations包已经支持52种语言,如果你想让你的应用在iOS上顺利运行,那么你还必须添加“flutter_cupertino_localizations”包。

pubspec.yaml文件中添加包依赖:

  1. dependencies:
  2. flutter:
  3. sdk: flutter
  4. flutter_localizations:
  5. sdk: flutter
  6. flutter_cupertino_localizations: ^1.0.1

设置如下:

  1. MaterialApp(
  2. localizationsDelegates: [
  3. // ... app-specific localization delegate[s] here
  4. GlobalMaterialLocalizations.delegate, //为Material Components库提供了本地化的字符串和其他值。
  5. GlobalWidgetsLocalizations.delegate, //定义widget默认的文本方向,从左到右或从右到左。
  6. GlobalCupertinoLocalizations.delegate, //为Cupertino(ios风格)库提供了本地化的字符串和其他值。
  7. ],
  8. // 指定了当前App支持的语言。
  9. supportedLocales: [
  10. // ... other locales the app supports
  11. const Locale('zh', 'CH'), // China
  12. const Locale('en', 'US'), // English
  13. ],
  14. ...
  15. )

localeResolutionCallbacklocaleListResolutionCallback都是对语言变化的监听,比如切换系统语言等,localeResolutionCallbacklocaleListResolutionCallback的区别是localeResolutionCallback返回的第一个参数是当前语言的Locale,而localeListResolutionCallback返回当前手机支持的语言集合,在早期的版本手机没有支持语言的集合,只显示当前语言,在设置->语言和地区的设置选项效果如下:
MaterialApp - 图2
在早期是没有红色区域的。

因此我们只需使用localeListResolutionCallback即可,通过用户手机支持的语言和当前App支持的语言返回一个语言选项。

通常情况下,如果用户的语言正好是App支持的语言,那么直接返回此语言,如果不支持,则返回一个默认的语言,用法如下:

  1. MaterialApp(
  2. localeListResolutionCallback:
  3. (List<Locale> locales, Iterable<Locale> supportedLocales) {
  4. if (locales.contains('zh')) {
  5. return Locale('zh');
  6. }
  7. return Locale('en');
  8. },
  9. ...
  10. )

在App中也可以通过如下方法获取区域设置:

  1. Locale myLocale = Localizations.localeOf(context);

debugShowMaterialGrid 打开网格调试

image.png

showPerformanceOverlay 打开性能检测

image.png

debugShowCheckedModeBanner 打开debug图标

image.png

showSemanticsDebugger 打开语义化调试

image.png