Flutter 手把手国际化

news2024/11/28 9:38:05

1.导入依赖

  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: any

2.安装插件Flutter Intl

Android Studio > File > Settings > Plugins 搜索Flutter Intl
并安装和重启Android Studio生效

3.通过插件初始化并配置语言

Android Studio > Tools > Flutter Intl > lnitialize for the Project
在这里插入图片描述
初始化后插件会自动创建
l10n.dart 语言管理类
messages_all.dart 语言管理类
messages_en.dart 英文
intl_en.arb 英文数据
路径为:
lib/generated/l10n.dart
lib/generated/intl/messages_all.dart
lib/generated/intl/messages_en.dart
lib/l10n/intl_en.arb

由此可知 插件只生成了英文版,所以我们需要手动加入中文配置

3.1配置中文

Android Studio > Tools > Flutter Intl > Add Locale 并输入zh
在这里插入图片描述
在这里插入图片描述
之后插件会生成对应的中文配置文件:
lib/generated/intl/messages_zh.dart
lib/l10n/intl_zh.arb

目前语言相关的文件已生成完,如下图
在这里插入图片描述
文件生成完了,接下来就是把中英文插入相应的位置了,
intl_zh.arb 和 intl_en.arb 分别代表中文和英文的语言数据,所以只需要修改它俩即可,其他文件会根据数据自动配置

3.2 加入语言数据

intl_zh.arb 和 intl_en.arb 是以json结构配置的,所以我们配置如下

lib/l10n/intl_zh.arb

{
  "str_download": "应用下载",
  "str_lang": "语言",
  "str_update": "检测更新",
  "str_about": "关于我们"
}

lib/l10n/intl_en.arb

{
  "str_download": "Application Download",
  "str_lang": "Language",
  "str_update": "Detect updates",
  "str_about": "About us"
}

语言配置好了,接下来就是怎么引用它们了。

4.使用国际化语言

4.1 页面引用语言字段

  _updateLang() async {
    AppLocalizationDelegate delegate = const AppLocalizationDelegate();
    //获取当前系统语言
    Locale myLocale = Localizations.localeOf(context);
    //根据当前语言获取对应的语言数据
    lang = await delegate.load(myLocale);
    //获取字段
    var update = lang.str_update;
    var about = lang.str_about;
  }

页面里面使用完整代码如下:

class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<StatefulWidget> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  @override
  void initState() {
    super.initState();
  }

  late S lang;

  _updateLang() async {
    AppLocalizationDelegate delegate = const AppLocalizationDelegate();
    //获取当前系统语言
    Locale myLocale = Localizations.localeOf(context);
    //根据当前语言获取对应的语言数据
    lang = await delegate.load(myLocale);
  }

  @override
  Widget build(BuildContext context) {
    _updateLang();
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0,
        title: Text("我的",
            style: TextStyle(
                fontSize: 30,
                color: AppColors.gray33,
                fontWeight: FontWeight.bold)),
      ),
      body: Container(
        child: Column(
          children: [
            Text(
              lang.str_download,
            ),
            Text(
              lang.str_lang,
            ),
            Text(
              lang.str_update,
            ),
            Text(
              lang.str_about,
            ),
          ],
        ),
      ),
    );
  }
}

这样页面里面的组件就引用到了语言管理类中的字段,但是还差一步初始化

4.2 main.dart中初始化语言配置

初始化插件生成的语言配置

      localizationsDelegates: const [
        AppLocalizationDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const AppLocalizationDelegate().supportedLocales,
      locale: locale,

完整代码如下

void main() {
//默认为中文
  var locale = Locale.fromSubtags(languageCode: 'zh');
  runApp(MyApp(locale));
}

class MyApp extends StatelessWidget {
  final Locale locale;

  const MyApp(this.locale, {super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue, primaryColor: Colors.white),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
      routes: {
        MyRouter.DOWNLOAD_PAGE: (context) => DownLoadPage(),
        MyRouter.LANG_PAGE: (context) => LangPage(),
      },
//初始化语言配置
      localizationsDelegates: const [
        AppLocalizationDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const AppLocalizationDelegate().supportedLocales,
      locale: locale,
    );
  }
}

这样语言就都配置好了,切换语言只需要调用
runApp(MyApp(locale))
传入对应语言参数即可。

5.切换语言

切换中文:

  var locale = Locale.fromSubtags(languageCode: 'zh');
  runApp(MyApp(locale));

切换英文:

var locale = Locale.fromSubtags(languageCode: 'en');
 runApp(MyApp(locale));

完整页面代码如下:

class LangPage extends StatelessWidget {
  const LangPage({super.key});

  //切换语言
  changeLang(Locale locale) {
    runApp(MyApp(locale));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: BaseAppBar("语言"),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            InkWell(
              onTap: () {
                var locale = Locale.fromSubtags(languageCode: BaseData.ZH);
                changeLang(locale);
                SPUtils.setLangCode(BaseData.ZH);
                Navigator.pop(context);
              },
              child: Container(
                padding: EdgeInsets.only(left: 16),
                height: 60,
                child: Align(
                  alignment: Alignment.centerLeft,
                  child: Text(
                    "简体中文",
                    style: TextStyle(fontSize: 16, color: AppColors.gray33),
                  ),
                ),
              ),
            ),
            Container(
              margin: EdgeInsets.only(left: 16),
              height: 0.5,
              color: AppColors.line,
            ),
            InkWell(
              onTap: () {
                var locale = Locale.fromSubtags(languageCode: BaseData.EN);
                changeLang(locale);
                SPUtils.setLangCode(BaseData.EN);
                Navigator.pop(context);
              },
              child: Container(
                padding: EdgeInsets.only(left: 16),
                height: 60,
                child: Align(
                  alignment: Alignment.centerLeft,
                  child: Text(
                    "English",
                    style: TextStyle(fontSize: 16, color: AppColors.gray33),
                  ),
                ),
              ),
            ),
            Container(
              margin: EdgeInsets.only(left: 16),
              height: 0.5,
              color: AppColors.line,
            ),
          ],
        ));
  }
}

class BaseData{
  static const String ZH = 'zh';
  static const String EN = 'en';
}

这样就实现了在 语言设置 页面进行语言切换了,但是重启app后语言又还原成中文了,所以采用shared_preferences库保存上一次语言

6.重启APP 恢复最近设置的语言

class SPUtils {
  static const String _LANG_KEY = "lang_key";

  static setLangCode(String langCode) async {
    var sp = await SharedPreferences.getInstance();
    sp.setString(_LANG_KEY, langCode);
  }

  static Future<String> getLangCode() async {
    var sp = await SharedPreferences.getInstance();
    return sp.getString(_LANG_KEY) ?? BaseData.ZH;
  }
}

在设置页面设置完成后保存语言类型

    SPUtils.setLangCode(BaseData.ZH);

在App重启的时候获取数据并且设置,所以修改后的main.dart如下:

void main() async {
  // makes sure plugins are initialized 确保Flutter应用程序的绑定已经初始化完成
  WidgetsFlutterBinding.ensureInitialized();
  //执行异步获取
  var langCode = await SPUtils.getLangCode();
  var locale = Locale.fromSubtags(languageCode: langCode);
  runApp(MyApp(locale));
}

class MyApp extends StatelessWidget {
  final Locale locale;

  const MyApp(this.locale, {super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue, primaryColor: Colors.white),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
      routes: {
        MyRouter.DOWNLOAD_PAGE: (context) => DownLoadPage(),
        MyRouter.LANG_PAGE: (context) => LangPage(),
      },
      localizationsDelegates: const [
        AppLocalizationDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const AppLocalizationDelegate().supportedLocales,
      locale: locale,
    );
  }
}

这里需要注意的是shared_preferences是异步获取的,所以要加上WidgetsFlutterBinding.ensureInitialized();

至此,语言切换完成。
最后附个版本:

sdks:
  dart: ">=3.1.0-185.0.dev <4.0.0"
  flutter: ">=3.7.0"

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【已解决】在linux部署出现java文件操作报错:java.io.FileNotFoundException

1.报错场景&#xff1a; 其中的 ip2region.xdb 文件是放在 resources 文件夹中的&#xff0c;然后在一个工具类里面读取这个文件&#xff0c;在开发环境中的是这样读取的&#xff1a; ClassPathResource resource new ClassPathResource("ip2region.xdb");//获取真…

NI-9505 嵌入式行业领先的流量校准测量算法

NI-9505 嵌入式行业领先的流量校准测量算法 基岩自动化公司&#xff0c;基岩OSA自动化平台的制造商&#xff0c;已经将流量计算机功能集成到OSA平台中。奥萨流程系列嵌入流量校准基岩自动化平台中的测量应用。Flow-Cal的软件是流量测量和生产核算数据的选择。 奥萨所有基岩控…

基于Python的豆瓣电影排行榜,可视化系统

1 简介 基于Python flask 的豆瓣电影数据获取&#xff0c;数据可视化系统&#xff0c;本系统朱亚奥包括了影视系统的爬虫与分析。影视是人们娱乐、放松心情的重要方式之一&#xff0c;因此对影视的分析具有重要的现实意义。通过采用Python编程语言&#xff0c;使用flask框架搭…

内部福利!双11百度文心一言底层的千帆大模型免费试用!

内部福利&#xff0c;现在可以免费试用&#xff0c;而且额度超高。双11福利 个人大模型平台新用户&#xff1a;50元&#xff1b;限量1000张&#xff1b;限时一个月使用 企业大模型平台新用户&#xff1a;200元&#xff1b;限量200张&#xff1b;限时一个月使用 EB4对标GPT4 …

GoLong的学习之路(十七)基础工具之GORM(操作数据库)(更新Update)

书接上回&#xff0c;上回写道&#xff0c;GORM的查询和创建&#xff08;插入数据&#xff09;&#xff0c;这回继续些增删改查的改和删的操作。 文章目录 更新update修改单个列修改多个列修改选定字段批量更新新阻止全局更新 使用 SQL 表达式更新注意 根据子查询进行更新不使用…

Spring boot 整合 JWT

系列文章目录 第一章 Java线程池技术应用 第二章 CountDownLatch和Semaphone的应用 第三章 Spring Cloud 简介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 第七章 Spring Cloud 之 GateWay 第八章 Sprin…

【WinForm详细教程六】WinForm中的GroupBox和Panel 、TabControl 、SplitContainer控件

文章目录 1.GroupBox和Panel2.TabControl3.SplitContainer 1.GroupBox和Panel GroupBox&#xff1a;是一个分组容器&#xff0c;提供一个框架将相关的控件组织在一起&#xff0c;它有标题、边框&#xff0c;但没有滚动条。 Panel&#xff1a;也是一个容器控件&#xff0c;用来…

Git GitHub同步失败

文章目录 错误解决方案第一步第二步第三步第四步第六步第七步 错误 昨天晚上提交代码到GitHub时遇到了这个错误。 remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.字面大体意思就是你原先的密码凭…

预约按摩小程序开发优势;

在快节奏和高压社会中&#xff0c;按摩已成为许多人缓解压力和保持健康的重要方式&#xff0c;各地的按摩店也是随处可见&#xff0c;而为了能够更好地提供服务&#xff0c;很多按摩店都引入了小程序应用。今天我们就主要了解一下按摩店小程序具体有什么用&#xff0c;能够提供…

【iOS免越狱】利用IOS自动化WebDriverAgent实现自动直播间自动输入

1.目标 由于看直播的时候主播叫我发 666&#xff0c;支持他&#xff0c;我肯定支持他呀&#xff0c;就一直发&#xff0c;可是后来发现太浪费时间了&#xff0c;能不能做一个直播间自动发 666 呢&#xff1f;于是就开始下面的操作。 2.操作环境 iPhone一台 WebDriverAgent …

CAD操作技巧学习总结

1&#xff0c;已知一个圆&#xff0c;画该圆切线。 L命令画直线&#xff0c;再tan指令确定第一个点为切点&#xff0c;依次输入&#xff08;长度&#xff09;<&#xff08;角度&#xff09;&#xff0c;如55<-45,负号为顺时针。 2&#xff0c;中心点偏移。 O命令偏移&am…

再学一点mybatis(原理分析)

文章目录 [TOC](文章目录) 一、mybatis是什么&#xff1f;1. Mybatis的特点以及优缺点 二、mybatis架构1.基本架构2.重要组件 三、原理1. SQL解析2. Mapper接口3. 动态代理4. SQL执行4.1 Executor4.2 StatementHandler4.3 ParameterHandler4.4 ResultHandler 文章内容有点长&am…

【蓝桥每日一题]-二分精确(保姆级教程 篇4) #kotori的设备 #银行贷款 #一元三次方程求解

今天讲二分精确题型 目录 题目&#xff1a;kotori的设备 思路&#xff1a; 题目&#xff1a;银行贷款 思路&#xff1a; 题目&#xff1a;一元三次方程求解 思路&#xff1a; 题目&#xff1a;kotori的设备 思路&#xff1a; 求&#xff1a;设备最长使用时间 二分查找&#…

Linux难学?大神告诉你,Linux到底该怎么自学!

文章目录 前言一、明白这些道理&#xff0c;Linux 就不难学二、五步学会 Linux 命令行&#xff0c;用好这本手册三、Linux 学习进阶之路 前言 知乎上有一条热门问答&#xff0c;问题是 “Linux为什么那么难&#xff1f;” 从问题来看&#xff0c;提问者还处在初学阶段。但他显…

Centos7扩容

Centos7扩容 保证虚拟机关机且没有快照的情况下按照下图进行操作&#xff1a; 设置好后开机&#xff0c;查看分区情况&#xff1a; [rootlocalhost ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 17G 12G 5.4G 69% / …

21款奔驰GLS450升级23P驾驶辅助 智驾出行

驾驶辅助和自动驾驶的区别就是需要人为去接管&#xff0c;虽然车辆会根据道路自己行驶&#xff0c;弯道上也能居中自动修正行驶&#xff0c;长时间不接管方向盘&#xff0c;系统会提示人为接管&#xff0c;这就是奔驰的23P驾驶辅助系统&#xff0c; 很多车友升级23P驾驶辅助系…

Git统计个人提交代码行数

目录 一、git bash打开二、查看个人提交的代码行数统计三、查看项目每个人提交的代码行数统计四、查询所有用户的提交总次数五、统计用户一段时间内的提交代码量 在实际开发中&#xff0c;常常会想查看自己对于某个项目的贡献&#xff0c;管理者会查看项目下各成员的贡献&#…

mysql、clickhouse时间日期加法

mysql 在’2023-10-27 23:59:59’上增加5秒&#xff1a; SELECT DATE_ADD(2023-10-27 23:59:59, INTERVAL 5 second);clickhouse SELECT date_add(SECOND, 3, toDate(2018-01-01 00:00:00));clickhouse时间按秒、分、时、日、月、年作差 按秒&#xff1a; SELECT dateDiff…

【DataGrip使用小技巧】

在日常开发中无论是连接数据库也好&#xff0c;编写代码也好都是通过DataGrip来实现的&#xff0c;在开发过程中有一些小技巧的使用可以使开发变得高效便捷。 【非常实用】要快速查看插入符号处的表或列的文档,请按 ctrl Q(查看快速文档)。 可以显示首几行的数据&#xff0c…

团队表 -多级团队设计

团队表 -多级团队设计 user_team团队表 &#xff0c;如果存在子团队 1.我们可以通过每一个团队字段加一个parentid &#xff08;相当于一对多的关系&#xff09; 2.还可以设置一个字段CodingNum,比如这样: //系统为了管理查询团队自动生成的有序编号 可以使用3位数代表一个…