【Flutter】多语言方案一:flutter

2024-06-04 8265阅读

介绍

多语言方案:flutter_localizations 与 GetX 配合版,好处:命令行生成多语言字符串的引用常量类,缺点:切换语言以后,主界面需要手动触发setState,重绘将最新的Locale数据设置给GetMaterialApp。


目录

  • 介绍
  • 运行效果
  • 一、安装
  • 二、使用
    • 1.lib文件夹中新建文件夹l10n/arb,并在其中创建app_en.arb 、app_zh.arb、app_zh_HK.arb文件
    • 2.项目的根目录中添加l10n.yaml,配置如下
    • 3.添加完成之后,执行命令`flutter gen-l10n`,执行命令`flutter run`,.dart_tools会自动生成相关的文件
    • 4.MaterialApp改成GetMaterialApp配置国际化字段
    • 5.调用
    • 6.多语言切换

      运行效果

      【Flutter】多语言方案一:flutter 第1张

      一、安装

      dependencies:
      flutter_localizations:
      sdk: flutter
      intl: any
      get: ^4.6.6
      flutter:
      uses-material-design: true
      generate: true
      

      二、使用

      1.lib文件夹中新建文件夹l10n/arb,并在其中创建app_en.arb 、app_zh.arb、app_zh_HK.arb文件

      app_en.arb类

      {
        "@@locale": "en",
        "appName": "BraveComponent",
        "@appName": {
            "description": "备注"
        },
        "helloWorld": "HelloWorld",
        "followerSystemLanguage": "FollowerSystemLanguage",
        "simplifiedChinese": "SimplifiedChinese",
        "traditionalChinese": "TraditionalChinese",
        "english": "English",
        "setting": "Setting",
        "multiLanguage": "MultiLanguage",
        "theme": "Theme"
      }
      

      app_zh.arb类

      {
        "@@locale": "zh",
        "appName": "BraveComponent",
        "@appName": {
            "description": "备注"
        },
        "helloWorld": "你好,世界",
        "followerSystemLanguage": "跟随系统语言",
        "simplifiedChinese": "简体中文",
        "traditionalChinese": "繁体中文",
        "english": "英文",
        "setting": "设置",
        "multiLanguage": "多语言",
        "theme": "主题"
      }
      

      app_zh.arb类

      {
         "@@locale": "zh_HK",
         "appName": "BraveComponent",
         "@appName": {
             "description": "備注"
         },
         "helloWorld": "妳好,世界",
         "followerSystemLanguage": "跟隨系統語言",
         "simplifiedChinese": "簡體中文",
         "traditionalChinese": "繁體中文",
         "english": "英文",
         "setting": "設置",
         "multiLanguage": "多語言",
         "theme": "主題"
      }
      

      2.项目的根目录中添加l10n.yaml,配置如下

      arb-dir: lib/l10n/arb
      template-arb-file: app_zh.arb
      output-localization-file: app_localizations.dart
      output-class: AppLocalizations
      use-deferred-loading: true
      nullable-getter: false
      

      3.添加完成之后,执行命令flutter gen-l10n,执行命令flutter run,.dart_tools会自动生成相关的文件

      【Flutter】多语言方案一:flutter 第2张

      4.MaterialApp改成GetMaterialApp配置国际化字段

      l10n_app.dart类代码

      import 'package:brave_component/core/utils/language_utils.dart';
      import 'package:flutter/material.dart';
      import 'package:flutter_localizations/flutter_localizations.dart';
      import 'package:get/get.dart';
      import 'l10n/l10n.dart';
      import 'routes/route_pages.dart';
      import 'routes/route_path.dart';
      class L10nApp extends StatefulWidget {
        bool _init = true;
        L10nApp({super.key});
        @override
        State createState() => L10nAppState();
      }
      class L10nAppState extends State {
        // 供外部使用的_AppSetting实例,用于修改app的状态
        static AppSetting setting = AppSetting.instance;
        @override
        void initState() {
          super.initState();
          //第一次进入app时,获取本地多语言的countryCode
          if (widget._init) {
            setting.setLocale();
            widget._init = false;
          }
          // 更改语言
          setting.changeLocale = () {
            setState(() {});
          };
        }
        @override
        Widget build(BuildContext context) {
          return GetMaterialApp(
            initialRoute: RoutePath.l10n_main,
            getPages: RoutePages.getPages,
            title: 'component',
            theme: ThemeData(
              colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
              useMaterial3: true,
            ),
            locale: setting._locale,
            fallbackLocale: const Locale("zh", "CN"),
            localeResolutionCallback: (deviceLocale, supportedLocales) {
              print('当前语言:${deviceLocale.toString()}');
              return;
            },
            supportedLocales: AppLocalizations.supportedLocales,
            localizationsDelegates: const [
              AppLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalMaterialLocalizations.delegate
            ],
          );
        }
      }
      class AppSetting {
        AppSetting._();
        static final AppSetting _instance = AppSetting._();
        static AppSetting get instance => _instance;
        Locale? _locale;
        Function()? changeLocale;
        void setLocale() {
          _locale = LanguageUtils.getLocale();
        }
      }
      

      language_utils.dart类代码

      import 'package:brave_component/l10n/l10n.dart';
      import 'package:flutter/widgets.dart';
      import 'package:get/get.dart';
      import '../../l10n_app.dart';
      import '../cache/helpers/cache_helper.dart';
      import '../enums/language.dart';
      class LanguageUtils {
        static String getLanguage(BuildContext context, String code) {
          late String language;
          switch (code) {
            case 'fs-Lan':
              language = context.l10n.followerSystemLanguage;
              break;
            case 'zh-CN':
              language = context.l10n.simplifiedChinese;
              break;
            case 'zh-HK':
              language = context.l10n.traditionalChinese;
              break;
            case 'en-US':
              language = context.l10n.english;
              break;
            default:
              language = context.l10n.followerSystemLanguage;
              break;
          }
          return language;
        }
        static Locale? getLocale() {
          Locale? locale;
          String code = CacheHelper.countryCode;
          List lang = code.split('-');
          locale = (code == Language.fsLan.countryCode)
              ? Get.deviceLocale
              : Locale(lang[0], lang[1]);
          return locale;
        }
        static void updateLocale(String countryCode, {bool isL10n = false}) {
          List lang = countryCode.split('-');
          Get.updateLocale((countryCode == Language.fsLan.countryCode)
              ? Get.deviceLocale!
              : Locale(lang[0], lang[1]));
          CacheHelper.saveCountryCode(countryCode);
          if (isL10n) {
            L10nAppState.setting.changeLocale!();
          }
        }
      }
      

      mian.dart类

      import 'package:flutter/material.dart';
      import 'app.dart';
      import 'core/cache/cache/cache.dart';
      import 'l10n_app.dart';
      void main() async {
        await Cache.instance.init();
        runApp(L10nApp()); //flutter_localizations与GetX配合版的多语言
        // runApp(const App()); //GetX版多语言
      }
      

      5.调用

      1. 直接使用 Text(AppLocalizations.of(context).helloWorld)
      2. 扩展使用

        - 扩展BuildContext

      extension BuildContextExtension on BuildContext {    
          AppLocalizations get l10n => AppLocalizations.of(this);    
      }
      
       - 使用   
       Text(context.l10n.helloWorld)  
      

      6.多语言切换

      l10n_multi_language_view.dart类

      import 'package:brave_component/core/enums/language.dart';
      import 'package:brave_component/l10n/l10n.dart';
      import 'package:flutter/material.dart';
      import 'package:get/get.dart';
      import '../../../../../core/res/colours.dart';
      import '../../../../../widgets/base/texts.dart';
      import 'l10n_multi_language_logic.dart';
      class L10nMultiLanguagePage extends StatelessWidget {
        L10nMultiLanguagePage({super.key});
        final logic = Get.find();
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: Texts.fontSize18Normal(context.l10n.multiLanguage,
                  color: Colours.titleColor),
              leading: GestureDetector(
                onTap: () {
                  Get.back(result: 'changeLanguage');
                },
                child: const Icon(Icons.arrow_back),
              ),
            ),
            body: Container(
              padding: const EdgeInsets.symmetric(vertical: 15),
              // child: ListView(
              //   children: ListTile.divideTiles(
              //           context: context,
              //           tiles: Language.values
              //               .map((e) =>
              //                   GetBuilder(builder: (logic) {
              //                     return ListTile(
              //                       title: Texts.fontSize14Normal(e.title,
              //                           color: Colours.titleColor),
              //                       trailing: e.countryCode == logic.countryCode
              //                           ? const Icon(Icons.check,
              //                               color: Colours.primaryColor)
              //                           : null,
              //                       onTap: () {
              //                         logic.changeLanguage(e.countryCode);
              //                       },
              //                     );
              //                   }))
              //               .toList())
              //       .toList(),
              // ),
              child: ListView.separated(
                  itemBuilder: (context, index) {
                    return _itemContent(context, index);
                  },
                  separatorBuilder: (_, index) => const Divider(),
                  itemCount: Language.values.length),
            ),
          );
        }
        Widget _itemContent(BuildContext context, int index) {
          return GetBuilder(builder: (logic) {
            return Container(
              padding: const EdgeInsets.symmetric(horizontal: 15),
              height: 44,
              child: GestureDetector(
                onTap: () {
                  logic.changeLanguage(Language.values[index].countryCode);
                },
                child: Row(
                  children: [
                    Expanded(
                        child: Texts.fontSize14Normal(Language.values[index].title,
                            color: Colours.titleColor)),
                    Visibility(
                        visible:
                            logic.countryCode == Language.values[index].countryCode,
                        child: const Icon(Icons.check, color: Colours.primaryColor))
                  ],
                ),
              ),
            );
          });
        }
      }
      

      l10n_multi_language_logic.dart类

      import 'package:brave_component/core/cache/helpers/cache_helper.dart';
      import 'package:brave_component/core/utils/language_utils.dart';
      import 'package:get/get.dart';
      class L10nMultiLanguageLogic extends GetxController {
        late String countryCode;
        @override
        void onInit() {
          super.onInit();
          countryCode = CacheHelper.countryCode;
        }
        void changeLanguage(String code) {
          countryCode = code;
          LanguageUtils.updateLocale(code, isL10n: true);//切换Locale
          update();
        }
      }
      

      l10n_multi_language_binding.dart类

      import 'package:get/get.dart';
      import 'l10n_multi_language_logic.dart';
      class L10nMultiLanguageBinding extends Bindings {
        @override
        void dependencies() {
          Get.lazyPut(() => L10nMultiLanguageLogic());
        }
      }
      

      language 类

      enum Language {
        fsLan(title: "跟随系统语言", countryCode: "fs-Lan"),
        zhCN(title: "简体中文", countryCode: "zh-CN"),
        zhHK(title: "繁体中文", countryCode: "zh-HK"),
        enUS(title: "English", countryCode: "en-US");
        final String title;
        final String countryCode;
        const Language({required this.title, required this.countryCode});
      }
      

      这里关于GetX的binding用法不会的可以参考Flutter GetX使用—简洁的魅力!这个博主开发的GetX插件,生成模版代码提高研发效率,建议看看用起来。

      持久化就不赘述了,参考源码

      源码

      下一篇 多语言方案二:GetX 版


    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]