3、 Flutter Intl
多语言国际化

在Android Studio中菜单Tools找到flutter intl创建多语言配置。
创建后会在pubspec.yaml出现
- flutter_intl:
- enabled: true

在工程的lib会生成l10n与generated文件夹
l10n包含
intl_en.arb
intl_zn.arb
我们在intl_en.arb添加
- {
- 'home': "Home",
- }
在intl_zn.arb添加
- {
- 'home': "首页",
- }
注意:每次修改完arb文件保存一下即可生效
创建LocalModel
- // 共享状态
- class SessionChangeNotifier with ChangeNotifier {
- Session get session => Global.session;
-
- String? get getToken => Global.session.token;
-
- @override
- void notifyListeners() {
- // 保存Profile变更
- Global.saveProfile();
-
- //通知依赖的Widget更新
- super.notifyListeners();
- }
- }
- class LocaleModel extends SessionChangeNotifier {
- // 获取当前用户的APP语言配置Locale类,如果为null,则语言跟随系统语言
- Locale? getLocale() {
- if (session.locale == null) return null;
- var t = session.locale?.split("_");
- LoggerManager().debug("getLocale t:${t}");
- if (t != null && t.length == 2) {
- LoggerManager().debug("Locale t:${t}");
- return Locale(t[0], t[1]);
- }
-
- return null;
- }
-
- // 获取当前Locale的字符串表示
- String get locale => session.locale ?? "";
-
- // 用户改变APP语言后,通知依赖项更新,新语言会立即生效
- set locale(String locale) {
- LoggerManager().debug("locale:${locale}, profile.locale:${session.locale}");
- if (locale != session.locale) {
- session.locale = locale;
- notifyListeners();
- }
- }
- }
在Main的入口中设置
- class MyApp extends StatelessWidget {
- const MyApp({Key? key}) : super(key: key);
-
- // This widget is the root of your application.
- @override
- Widget build(BuildContext context) {
- return MultiProvider(
- providers: providers,
- child: Consumer3<ThemeModel, LocaleModel, UserModel>(
- builder: (context, themeModel, localeModel, userModel, child) {
- return RefreshConfiguration(
- hideFooterWhenNotFull: false, //列表数据不满一页,不触发加载更多
- child: ScreenUtilInit(
- designSize: const Size(375.0, 667.0),
- minTextAdapt: true,
- splitScreenMode: true,
- builder: (context, child) {
- return child ??
- buildMaterialApp(
- context, localeModel, themeModel, userModel);
- },
- child:
- buildMaterialApp(context, localeModel, themeModel, userModel),
- ),
- );
- },
- ),
- );
- }
-
- Widget buildMaterialApp(BuildContext context, LocaleModel localeModel,
- ThemeModel themeModel, UserModel userModel) {
- return MaterialApp(
- theme: ThemeData(
- fontFamily: "PingFang SC",
- primarySwatch: themeModel.theme,
- ),
- navigatorKey: OneContext().key,
- debugShowCheckedModeBanner: false,
- supportedLocales: S.delegate.supportedLocales,
- locale: localeModel.getLocale(),
- initialRoute: buildInitialRoute(
- appModel: Provider.of<AppModel>(context, listen: false),
- userModel: userModel,
- ),
- onGenerateRoute: RouterManager.generateRoute,
- navigatorObservers: buildObservers(),
- localizationsDelegates: const [
- S.delegate,
- RefreshLocalizations.delegate, //下拉刷新
- GlobalCupertinoLocalizations.delegate,
- GlobalMaterialLocalizations.delegate,
- GlobalWidgetsLocalizations.delegate
- ],
- localeResolutionCallback: (_locale, supportedLocales) {
- if (localeModel.getLocale() != null) {
- //如果已经选定语言,则不跟随系统
- return localeModel.getLocale();
- } else {
- //跟随系统
- LoggerManager().debug("_locale:${_locale}");
- Locale locale;
- if (supportedLocales.contains(_locale)) {
- locale = _locale!;
- } else {
- //如果系统语言不是中文简体或美国英语,则默认使用美国英语
- locale = Locale('en', 'US');
- }
- return locale;
- }
- },
- builder: EasyLoading.init(builder: (BuildContext context, Widget? child) {
- return OneContext().builder(
- context,
- child,
- observers: buildObservers(),
- );
- }),
- home: buildGlobalGesture(context),
- );
- }
-
- Widget buildGlobalGesture(BuildContext context) {
- return GestureDetector(
- onTap: () {
- FocusScopeNode currentFocus = FocusScope.of(context);
- if (!currentFocus.hasPrimaryFocus &&
- currentFocus.focusedChild != null) {
- FocusManager.instance.primaryFocus?.unfocus();
- // 也可以使用如下方式隐藏键盘:
- // SystemChannels.textInput.invokeMethod('TextInput.hide');
- }
- },
- );
- }
-
- List<NavigatorObserver> buildObservers() {
- return [MyNavigatorObserver()];
- }
-
- String? buildInitialRoute(
- {required AppModel appModel, required UserModel userModel}) {
- String? initialRoute;
- // String? isAgree = localeModel.isAgree;
- String? isAgree = "1";
- if ("1" == isAgree) {
- if (userModel.isLogin) {
- initialRoute = RouterName.main;
- } else {
- initialRoute = RouterName.login;
- }
- } else {
- initialRoute = RouterName.agreement;
- }
- return initialRoute;
- }
- }
之后我们可以在具体使用的地方这个配置的home。
- return Scaffold(
- appBar: MyAppBar(
- label: S.of(context).home,
- isBackButton: false,
- ),
- body:Container(),);
更换语言环境页面
- class LanguagePage extends StatefulWidget {
- const LanguagePage({Key? key, this.arguments}) : super(key: key);
-
- final Object? arguments;
-
- @override
- State<LanguagePage> createState() => _LanguagePageState();
- }
-
- class _LanguagePageState extends State<LanguagePage> {
- @override
- Widget build(BuildContext context) {
- var color = Theme.of(context).primaryColor;
- var localeModel = Provider.of<LocaleModel>(context);
- Widget _buildLanguageItem(String lan, value) {
- LoggerManager().debug("_buildLanguageItem:${lan}, value:${value}");
- return SettingCheckItemWidget(
- title: lan,
- content: "",
- checkColor: color,
- isSelected: localeModel.locale == value,
- onPressed: () {
- // 此行代码会通知MaterialApp重新build
- localeModel.locale = value;
- },
- );
- }
-
- return Scaffold(
- appBar: MyAppBar(
- onPressed: () {
- navigatorBack();
- },
- label: S.of(context).language,
- isBackButton: true,
- ),
- body: ListView.builder(
- padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 10.0),
- addRepaintBoundaries: false,
- addAutomaticKeepAlives: false,
- itemCount: 3,
- itemBuilder: (context, index) {
- if (index == 0) {
- return _buildLanguageItem("中文简体", "zh_CN");
- }
-
- if (index == 1) {
- return _buildLanguageItem("English", "en_US");
- }
-
- if (index == 2) {
- return _buildLanguageItem(S.of(context).autoBySystem, null);
- }
- return Container();
- },
- ),
- );
- }
-
- void userEnterApp() {
- // 点击进入app
- NavigatorPageRouter.pushReplacementNamed(RouterName.main);
- }
-
- void navigatorBack() {
- NavigatorPageRouter.pop();
- }
- }