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

系列文章目录

多语言方案: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.多语言切换
      • 源码


一、安装

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文件

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());
  }
}

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

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

源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/556049.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Leetcode每日一题】 分治 - 排序数组(难度⭐⭐)(60)

1. 题目解析 题目链接&#xff1a;912. 排序数组 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 算法思路&#xff1a; 快速排序作为一种经典的排序算法&#xff0c;其核心思想在于通过“分而治之”的策略&#xff…

Idea修改【Help->Edit Custom VM Options...】后,导致idea无法正常启动的解决方法

一、错误场景: 二、解决方法&#xff1a; 修改文件路径&#xff1a;C:\Users\tianjm&#xff08;写自己的用户名&#xff09;\AppData\Roaming\JetBrains\IdeaIC2024.1&#xff08;选自己安装的版本&#xff09;

Linux 网络编程项目--简易ftp

主要代码 config.h #define LS 0 #define GET 1 #define PWD 2#define IFGO 3#define LCD 4 #define LLS 5 #define CD 6 #define PUT 7#define QUIT 8 #define DOFILE 9struct Msg {int type;char data[1024];char secondBuf[128]; }; 服务器: #i…

传统零售行业如何做数字化转型?

传统零售行业的数字化转型是一个系统性的过程&#xff0c;涉及到企业的多个方面。以下是一些关键步骤和策略&#xff0c;帮助传统零售企业实现数字化转型&#xff1a; 1、明确转型目标和战略 首先&#xff0c;企业需要明确数字化转型的目标和战略。包括确定企业的核心竞争力、…

Java内存模型和 JVM 内存运行时

文章目录 前言一、什么是Java 的内存模型&#xff1f;二、什么是 JVM 的运行时数据区Java8 之前和之后的区别JVM 内存模型JVM 内存区域JVM 内存垃圾回收JVM如何判断哪些对象不在存活&#xff1f;JVM运行过程中如何判断哪些对象是垃圾&#xff1f; JVM 垃圾回收Java8 中的 jvm如…

.rmallox勒索病毒来袭:如何守护您的数据安全?

引言&#xff1a; 随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显&#xff0c;其中勒索病毒更是成为了网络安全领域的一大难题。.rmallox勒索病毒作为一种典型的恶意软件&#xff0c;通过加密受害者文件并勒索赎金的方式&#xff0c;给企业和个人带来了巨大的经济损…

指纹浏览器如何高效帮助TikTok账号矩阵搭建?

TikTok的账号矩阵&#xff0c;可能听起来还比较陌生&#xff0c;但随着TikTok业务已经成为吃手可热的跨境业务&#xff0c;TikTok多账号矩阵已成为流行策略。但它有什么优点呢&#xff1f;操作多个帐户会导致被禁止吗&#xff1f;如何有效地建立账户矩阵开展业务&#xff1f;这…

爬虫 | 基于 requests 实现加密 POST 请求发送与身份验证

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本项目旨在实现一个简单的 Python 脚本&#xff0c;用于向指定的 URL 发送 POST 请求&#xff0c;并通过特定的加密算法生成请求头中的签名信息。这个脚本的背后是与某个特定的网络服务交互&#xff0c;发送特定格式的 JSON 数据…

深入理解MySQL中的UPDATE JOIN语句

在MySQL数据库中&#xff0c;UPDATE语句用于修改表中现有的记录。有时&#xff0c;我们需要根据另一个相关联表中的条件来更新表中的数据。这时就需要使用UPDATE JOIN语句。最近我们遇到了这样的需求&#xff1a;我们有一张历史记录表&#xff0c;其中一个字段记录了用,连接的多…

网络爬虫软件学习

1 什么是爬虫软件 爬虫软件&#xff0c;也称为网络爬虫或网络蜘蛛&#xff0c;是一种自动抓取万维网信息的程序或脚本。它基于一定的规则&#xff0c;自动地访问网页并抓取需要的信息。爬虫软件可以应用于大规模数据采集和分析&#xff0c;广泛应用于舆情监测、品牌竞争分析、…

在 Linux 终端中创建目录

目录 ⛳️推荐 前言 在 Linux 中创建一个新目录 创建多个新目录 创建多个嵌套的子目录 测试你的知识 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 前言 在本系列的这一部…

Day09 React———— 第九天

ReactRoter 一个路径 path 对应一个组件 component 当我们在浏览器中访问一个 path 的时候&#xff0c;path 对应的组件会在页面中进行渲染 基础用法 import { createBrowserRouter, RouterProvider } from "react-router-dom"; const router createBrowserRoute…

解决Mac使用Vscode无法调用外部终端

前言 今天遇到一个很奇怪的问题&#xff0c;之前好好的用Vscode还能调用外部终端&#xff0c;怎么今天不行了&#xff1f;问题出在哪里呢&#xff1f;请听我娓娓道来。 检查配置文件 我查看了一下配置文件&#xff0c;发现配置文件都是调用外部控制台&#xff0c;没毛病啊。 …

linux启动minicom、u-boot的常用命令、网络命令tftp、nfs/根文件系统、u-boot的bootargs环境变量

linux启动minicom sudo minicom -con进入minicom界面&#xff1a; 打开单片机 在打开之后&#xff0c;我们通过 printenv查看环境配置 在修改配置之前&#xff0c;我们最好先将环境初始化一下&#xff0c;初始化代码为 nand erase.chipu-boot的常用命令 尽管u-boot是一个…

Torch 模型 感受野可视化

前言&#xff1a;感受野是卷积神经网络 (CNN) 中一个重要的概念&#xff0c;它表示 CNN 每一层输出的特征图上的像素点在输入图像上映射的区域。感受野的大小和形状直接影响到网络对输入图像的感知范围和精度&#xff0c;进而调整网络结构、卷积核大小和步长等参数&#xff0c;…

后端-MySQL-week11 多表查询

tips: distinct————紧跟“select”之后&#xff0c;用于去重 多表查询 概述 一对多&#xff08;多对一&#xff09; 多对多 一对一 多表查询概述 分类 连接查询 内连接 外连接 自连接 必须起别名&#xff01; 联合查询-union&#xff0c;union all 子查询 概念 分类 …

OpenMesh 极小曲面(局部迭代法)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 我们的目标是想得到一个曲率处处为0的曲面,具体操作如下所述: 二、实现代码 #define _USE_MATH_DEFINES #include

量子时代加密安全与区块链应用的未来

量子时代加密安全与区块链应用的未来 现代密码学仍然是一门相对年轻的学科&#xff0c;但其历史却显示了一种重要的模式。大多数的发展都是基于几年甚至几十年前的研究。而这种缓慢的发展速度也是有原因的&#xff0c;就像药物和疫苗在进入市场之前需要经过多年的严格测试一样&…

【Web】2022DASCTF X SU 三月春季挑战赛 题解(全)

目录 ezpop calc upgdstore ezpop 瞪眼看链子 fin#__destruct -> what#__toString -> fin.run() -> crow#__invoke -> fin#__call -> mix.get_flag() exp <?php class crow {public $v1;public $v2;}class fin {public $f1; }class what {public $a; }…

MATLAB中gurobi 运行报错与调试

问题背景如下&#xff1a;刚拿到一份MATLAB的代码&#xff0c;但是电脑第一次安装gurobi&#xff0c;在运行过程中发生了报错&#xff0c;使用断点进行调试和步进调试方法&#xff0c;最终发现&#xff0c;这个问题出在了哪一步&#xff0c;然后向了人工智能和CSDN、百度寻求答…