main
函数为APP入口函数,实现如下:
void main() => Global.init().then((e) => runApp(MyApp()));
初始化完成后才会加载UI(MyApp
),MyApp
是应用的入口Widget,实现如下:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ThemeModel()),
ChangeNotifierProvider(create: (_) => UserModel()),
ChangeNotifierProvider(create: (_) => LocaleModel()),
],
child: Consumer2<ThemeModel, LocaleModel>(
builder: (BuildContext context, themeModel, localeModel, child) {
return MaterialApp(
theme: ThemeData(
primarySwatch: themeModel.theme,
),
onGenerateTitle: (context){
return GmLocalizations.of(context).title;
},
home: HomeRoute(),
locale: localeModel.getLocale(),
//我们只支持美国英语和中文简体
supportedLocales: [
const Locale('en', 'US'), // 美国英语
const Locale('zh', 'CN'), // 中文简体
//其他Locales
],
localizationsDelegates: [
// 本地化的代理类
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GmLocalizationsDelegate()
],
localeResolutionCallback: (_locale, supportedLocales) {
if (localeModel.getLocale() != null) {
//如果已经选定语言,则不跟随系统
return localeModel.getLocale();
} else {
//跟随系统
Locale locale;
if (supportedLocales.contains(_locale)) {
locale= _locale!;
} else {
//如果系统语言不是中文简体或美国英语,则默认使用美国英语
locale= Locale('en', 'US');
}
return locale;
}
},
// 注册路由表
routes: <String, WidgetBuilder>{
"login": (context) => LoginRoute(),
"themes": (context) => ThemeChangeRoute(),
"language": (context) => LanguageRoute(),
},
);
},
),
);
}
}
在上面的代码中:
- 根widget是
MultiProvider
,它将主题、用户、语言三种状态绑定到了应用的根上,如此一来,任何路由中都可以通过Provider.of()
来获取这些状态,也就是说这三种状态是全局共享的! HomeRoute
是应用的主页。- 在构建
MaterialApp
时,配置了APP支持的语言列表,以及监听了系统语言改变事件;另外MaterialApp
消费(依赖)了ThemeModel
和LocaleModel
,所以当APP主题或语言改变时MaterialApp
会重新构建 - 我们注册了命名路由表,以便在APP中可以直接通过路由名跳转。