還記得第一個看到的Flutter元件嗎?

mengqingdong1發表於2020-03-21

還記得第一個看到的Flutter元件嗎?

注意:無特殊說明,Flutter版本及Dart版本如下:

  • Flutter版本: 1.12.13+hotfix.5
  • Dart版本: 2.7.0

MaterialApp

在學習Flutter的過程中我們第一個看見的控制元件應該就是MaterialApp,畢竟建立一個新的Flutter專案的時候,專案第一個元件就是MaterialApp,這是一個Material風格的根控制元件,基本用法如下:

MaterialApp(
  home: Scaffold(
    appBar: AppBar(
      title: Text('老孟'),
    ),
  ),
)
複製程式碼

home引數是App預設顯示的頁面,效果如下:

還記得第一個看到的Flutter元件嗎?

title引數是應用程式的描述,在Android上,在工作管理員的應用程式快照上面顯示,在IOS上忽略此屬性,IOS上工作管理員應用程式快照上面顯示的是Info.plist檔案中的CFBundleDisplayName。如果想根據區域顯示不同的描述使用onGenerateTitle,用法如下:

MaterialApp(
  title: '老孟',
  onGenerateTitle: (context) {
    var local = Localizations.localeOf(context);
    if (local.languageCode == 'zh') {
      return '老孟';
    }
    return 'laomeng';
  },
  ...
)
複製程式碼

routesinitialRouteonGenerateRouteonUnknownRoute是和路由相關的4個屬性,路由簡單的理解就是頁面,路由的管理通常是指頁面的管理,比如跳轉、返回等。

MaterialApp按照如下的規則匹配路由:

  1. 路由為/home不為null則使用home
  2. 使用routes指定的路由。
  3. 使用onGenerateRoute生成的路由,處理除homeroutes以外的路由。
  4. 如果上面都不匹配則呼叫onUnknownRoute

是不是還是比較迷糊,不要緊,看下面的例子就明白了:

MaterialApp(
  routes: {
    'container': (context) => ContainerDemo(),
    'fitted': (context) => FittedBoxDemo(),
    'icon': (context) => IconDemo(),
  },
  initialRoute: '/',
  home: Scaffold(
    appBar: AppBar(
      title: Text('老孟'),
    ),
  ),
  onGenerateRoute: (RouteSettings routeSettings){
        print('onGenerateRoute:$routeSettings');
        if(routeSettings.name == 'icon'){
          return MaterialPageRoute(builder: (context){
            return IconDemo();
          });
        }
      },
      onUnknownRoute: (RouteSettings routeSettings){
        print('onUnknownRoute:$routeSettings');
        return MaterialPageRoute(builder: (context){
          return IconDemo();
        });
      },
  ...
)
複製程式碼

initialRoute設定為/,那麼載入home頁面。

如果initialRoute設定為icon,在routes中存在,所以載入routes中指定的路由,即IconDemo頁面。

如果initialRoute設定為icons1,此時routes中並不存在名稱為icons1的路由,呼叫onGenerateRoute,如果onGenerateRoute返回路由頁面,則載入此頁面,如果返回的是null,且home不為null,則載入home引數指定的頁面,如果home為null,則回撥onUnknownRoute

themedarkThemethemeMode是關於主題的引數,設定整個App的主題,包括顏色、字型、形狀等,修改主題顏色為紅色用法如下:

MaterialApp(
  theme: ThemeData(
    primaryColor: Colors.red
  ),
  darkTheme: ThemeData(
      primaryColor: Colors.red
  ),
  themeMode: ThemeMode.dark,
複製程式碼

效果如下:

還記得第一個看到的Flutter元件嗎?

localelocalizationsDelegateslocaleListResolutionCallbacklocaleResolutionCallbacksupportedLocales是區域設定和國際化相關的引數,如果App支援多國語言,那麼就需要設定這些引數,預設情況下,Flutter僅支援美國英語,如果想要新增其他語言支援則需要指定其他MaterialApp屬性,並引入flutter_localizations 包,到2019年4月,flutter_localizations包已經支援52種語言,如果你想讓你的應用在iOS上順利執行,那麼你還必須新增“flutter_cupertino_localizations”包。

pubspec.yaml檔案中新增包依賴:

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  flutter_cupertino_localizations: ^1.0.1

複製程式碼

設定如下:

MaterialApp(
  localizationsDelegates: [
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate
  ],
  supportedLocales: [
    const Locale('zh', 'CH'),
    const Locale('en', 'US'),
  ],
  ...
)
複製程式碼
  • GlobalMaterialLocalizations.delegate :為Material Components庫提供了本地化的字串和其他值。
  • GlobalWidgetsLocalizations.delegate:定義widget預設的文字方向,從左到右或從右到左。
  • GlobalCupertinoLocalizations.delegate:為Cupertino(ios風格)庫提供了本地化的字串和其他值。

supportedLocales引數指定了當前App支援的語言。

localeResolutionCallbacklocaleListResolutionCallback都是對語言變化的監聽,比如切換系統語言等,localeResolutionCallbacklocaleListResolutionCallback的區別是localeResolutionCallback返回的第一個引數是當前語言的Locale,而localeListResolutionCallback返回當前手機支援的語言集合,在早期的版本手機沒有支援語言的集合,只顯示當前語言,在設定->語言和地區的設定選項效果如下:

還記得第一個看到的Flutter元件嗎?

在早期是沒有紅色區域的。

因此我們只需使用localeListResolutionCallback即可,通過使用者手機支援的語言和當前App支援的語言返回一個語言選項。

通常情況下,如果使用者的語言正好是App支援的語言,那麼直接返回此語言,如果不支援,則返回一個預設的語言,用法如下:

MaterialApp(
  localeListResolutionCallback:
      (List<Locale> locales, Iterable<Locale> supportedLocales) {
    if (locales.contains('zh')) {
      return Locale('zh');
    }
    return Locale('en');
  },
  ...
)
複製程式碼

在App中也可以通過如下方法獲取區域設定:

Locale myLocale = Localizations.localeOf(context);
複製程式碼

還有幾個方便除錯的選項,debugShowMaterialGrid:開啟網格除錯

MaterialApp(
  debugShowMaterialGrid: true,
複製程式碼

效果如下:

還記得第一個看到的Flutter元件嗎?

showPerformanceOverlay:開啟效能檢測

MaterialApp(
  showPerformanceOverlay: true,
複製程式碼

效果如下:

還記得第一個看到的Flutter元件嗎?

右上角有一個DEBUG的標識,這是系統在debug模式下預設顯示的,不顯示的設定如下:

MaterialApp(
  debugShowCheckedModeBanner: true,
  ...
)
複製程式碼

CupertinoApp

我想你一定能想到既然有Material風格的MaterialApp,那麼也應該有Cupertino(ios)風格與之相對應,是的Cupertino風格的是CupertinoApp,CupertinoApp的屬性及用法和MaterialApp一模一樣,就不在具體介紹了。

歡迎加入Flutter的微信交流群(laomengit),一起學習,一起進步,生活不止眼前的苟且,還有詩和《遠方》。

當然我也非常希望您關注我個人的公眾號,裡面有各種福利等著大家哦。

還記得第一個看到的Flutter元件嗎?

相關文章