• flutter plugins插件【三】【Flutter Intl】


    3、 Flutter Intl

    多语言国际化

     在Android Studio中菜单Tools找到flutter intl创建多语言配置。

    创建后会在pubspec.yaml出现

    1. flutter_intl:
    2. enabled: true

    在工程的lib会生成l10n与generated文件夹

    l10n包含
    intl_en.arb
    intl_zn.arb

    我们在intl_en.arb添加

    1. {
    2. 'home': "Home",
    3. }

    在intl_zn.arb添加

    1. {
    2. 'home': "首页",
    3. }

    注意:每次修改完arb文件保存一下即可生效

    三、编写代码

    创建LocalModel

    1. // 共享状态
    2. class SessionChangeNotifier with ChangeNotifier {
    3. Session get session => Global.session;
    4. String? get getToken => Global.session.token;
    5. @override
    6. void notifyListeners() {
    7. // 保存Profile变更
    8. Global.saveProfile();
    9. //通知依赖的Widget更新
    10. super.notifyListeners();
    11. }
    12. }
    1. class LocaleModel extends SessionChangeNotifier {
    2. // 获取当前用户的APP语言配置Locale类,如果为null,则语言跟随系统语言
    3. Locale? getLocale() {
    4. if (session.locale == null) return null;
    5. var t = session.locale?.split("_");
    6. LoggerManager().debug("getLocale t:${t}");
    7. if (t != null && t.length == 2) {
    8. LoggerManager().debug("Locale t:${t}");
    9. return Locale(t[0], t[1]);
    10. }
    11. return null;
    12. }
    13. // 获取当前Locale的字符串表示
    14. String get locale => session.locale ?? "";
    15. // 用户改变APP语言后,通知依赖项更新,新语言会立即生效
    16. set locale(String locale) {
    17. LoggerManager().debug("locale:${locale}, profile.locale:${session.locale}");
    18. if (locale != session.locale) {
    19. session.locale = locale;
    20. notifyListeners();
    21. }
    22. }
    23. }

    在Main的入口中设置

    1. class MyApp extends StatelessWidget {
    2. const MyApp({Key? key}) : super(key: key);
    3. // This widget is the root of your application.
    4. @override
    5. Widget build(BuildContext context) {
    6. return MultiProvider(
    7. providers: providers,
    8. child: Consumer3<ThemeModel, LocaleModel, UserModel>(
    9. builder: (context, themeModel, localeModel, userModel, child) {
    10. return RefreshConfiguration(
    11. hideFooterWhenNotFull: false, //列表数据不满一页,不触发加载更多
    12. child: ScreenUtilInit(
    13. designSize: const Size(375.0, 667.0),
    14. minTextAdapt: true,
    15. splitScreenMode: true,
    16. builder: (context, child) {
    17. return child ??
    18. buildMaterialApp(
    19. context, localeModel, themeModel, userModel);
    20. },
    21. child:
    22. buildMaterialApp(context, localeModel, themeModel, userModel),
    23. ),
    24. );
    25. },
    26. ),
    27. );
    28. }
    29. Widget buildMaterialApp(BuildContext context, LocaleModel localeModel,
    30. ThemeModel themeModel, UserModel userModel) {
    31. return MaterialApp(
    32. theme: ThemeData(
    33. fontFamily: "PingFang SC",
    34. primarySwatch: themeModel.theme,
    35. ),
    36. navigatorKey: OneContext().key,
    37. debugShowCheckedModeBanner: false,
    38. supportedLocales: S.delegate.supportedLocales,
    39. locale: localeModel.getLocale(),
    40. initialRoute: buildInitialRoute(
    41. appModel: Provider.of<AppModel>(context, listen: false),
    42. userModel: userModel,
    43. ),
    44. onGenerateRoute: RouterManager.generateRoute,
    45. navigatorObservers: buildObservers(),
    46. localizationsDelegates: const [
    47. S.delegate,
    48. RefreshLocalizations.delegate, //下拉刷新
    49. GlobalCupertinoLocalizations.delegate,
    50. GlobalMaterialLocalizations.delegate,
    51. GlobalWidgetsLocalizations.delegate
    52. ],
    53. localeResolutionCallback: (_locale, supportedLocales) {
    54. if (localeModel.getLocale() != null) {
    55. //如果已经选定语言,则不跟随系统
    56. return localeModel.getLocale();
    57. } else {
    58. //跟随系统
    59. LoggerManager().debug("_locale:${_locale}");
    60. Locale locale;
    61. if (supportedLocales.contains(_locale)) {
    62. locale = _locale!;
    63. } else {
    64. //如果系统语言不是中文简体或美国英语,则默认使用美国英语
    65. locale = Locale('en', 'US');
    66. }
    67. return locale;
    68. }
    69. },
    70. builder: EasyLoading.init(builder: (BuildContext context, Widget? child) {
    71. return OneContext().builder(
    72. context,
    73. child,
    74. observers: buildObservers(),
    75. );
    76. }),
    77. home: buildGlobalGesture(context),
    78. );
    79. }
    80. Widget buildGlobalGesture(BuildContext context) {
    81. return GestureDetector(
    82. onTap: () {
    83. FocusScopeNode currentFocus = FocusScope.of(context);
    84. if (!currentFocus.hasPrimaryFocus &&
    85. currentFocus.focusedChild != null) {
    86. FocusManager.instance.primaryFocus?.unfocus();
    87. // 也可以使用如下方式隐藏键盘:
    88. // SystemChannels.textInput.invokeMethod('TextInput.hide');
    89. }
    90. },
    91. );
    92. }
    93. List<NavigatorObserver> buildObservers() {
    94. return [MyNavigatorObserver()];
    95. }
    96. String? buildInitialRoute(
    97. {required AppModel appModel, required UserModel userModel}) {
    98. String? initialRoute;
    99. // String? isAgree = localeModel.isAgree;
    100. String? isAgree = "1";
    101. if ("1" == isAgree) {
    102. if (userModel.isLogin) {
    103. initialRoute = RouterName.main;
    104. } else {
    105. initialRoute = RouterName.login;
    106. }
    107. } else {
    108. initialRoute = RouterName.agreement;
    109. }
    110. return initialRoute;
    111. }
    112. }

     之后我们可以在具体使用的地方这个配置的home。

    1. return Scaffold(
    2. appBar: MyAppBar(
    3. label: S.of(context).home,
    4. isBackButton: false,
    5. ),
    6. body:Container(),);

    更换语言环境页面

    1. class LanguagePage extends StatefulWidget {
    2. const LanguagePage({Key? key, this.arguments}) : super(key: key);
    3. final Object? arguments;
    4. @override
    5. State<LanguagePage> createState() => _LanguagePageState();
    6. }
    7. class _LanguagePageState extends State<LanguagePage> {
    8. @override
    9. Widget build(BuildContext context) {
    10. var color = Theme.of(context).primaryColor;
    11. var localeModel = Provider.of<LocaleModel>(context);
    12. Widget _buildLanguageItem(String lan, value) {
    13. LoggerManager().debug("_buildLanguageItem:${lan}, value:${value}");
    14. return SettingCheckItemWidget(
    15. title: lan,
    16. content: "",
    17. checkColor: color,
    18. isSelected: localeModel.locale == value,
    19. onPressed: () {
    20. // 此行代码会通知MaterialApp重新build
    21. localeModel.locale = value;
    22. },
    23. );
    24. }
    25. return Scaffold(
    26. appBar: MyAppBar(
    27. onPressed: () {
    28. navigatorBack();
    29. },
    30. label: S.of(context).language,
    31. isBackButton: true,
    32. ),
    33. body: ListView.builder(
    34. padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 10.0),
    35. addRepaintBoundaries: false,
    36. addAutomaticKeepAlives: false,
    37. itemCount: 3,
    38. itemBuilder: (context, index) {
    39. if (index == 0) {
    40. return _buildLanguageItem("中文简体", "zh_CN");
    41. }
    42. if (index == 1) {
    43. return _buildLanguageItem("English", "en_US");
    44. }
    45. if (index == 2) {
    46. return _buildLanguageItem(S.of(context).autoBySystem, null);
    47. }
    48. return Container();
    49. },
    50. ),
    51. );
    52. }
    53. void userEnterApp() {
    54. // 点击进入app
    55. NavigatorPageRouter.pushReplacementNamed(RouterName.main);
    56. }
    57. void navigatorBack() {
    58. NavigatorPageRouter.pop();
    59. }
    60. }

  • 相关阅读:
    深度系统v15.4正式发布,惊艳眼球
    [学习分享]指数移动平均
    【数据库】实验一 openGauss数据库管理系统
    不可忽视的字符函数与字符串函数:它们如何改变你的编程世界
    vue源码分析-事件机制
    vscode使用远程服务器jupyter
    js创建一个按钮添加到body中,设置宽度100px,高度30px,按钮文字一键登录,并为其添加点击事件
    (pytorch进阶之路)NormalizingFlow标准流
    java毕业设计一点就到家外卖订餐系统Mybatis+系统+数据库+调试部署
    分布式事务最终一致性的简单案例
  • 原文地址:https://blog.csdn.net/allanGold/article/details/132636926