【Flutter】多语言方案一:flutter_localizations 与 GetX 配合版

avatar
作者
筋斗云
阅读量:0

介绍

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


目录


运行效果

在这里插入图片描述

一、安装

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会自动生成相关的文件

在这里插入图片描述

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<L10nApp> createState() => L10nAppState(); }  class L10nAppState extends State<L10nApp> {   // 供外部使用的_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<String> 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<String> 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<L10nMultiLanguageLogic>();    @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<MultiLanguageLogic>(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<L10nMultiLanguageLogic>(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 版

    广告一刻

    为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!