flutter开发实战-多语言flutter intl

news2024/11/17 17:52:39

flutter开发实战-多语言flutter intl

之前做的应用中有用到多语言,一直没有整理,这里整理一下多语言设置流程。
使用的是Android studio

一、flutter_intl 插件

使用Android studio安装flutter_intl 插件,更新或者安装flutter_intl 插件后会提示重新启动IDE。

如图所示:
在这里插入图片描述

二、使用fluter_intl插件

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

在这里插入图片描述

创建后会在pubspec.yaml出现

flutter_intl:
  enabled: true

如图所示
在这里插入图片描述

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

l10n包含
intl_en.arb
intl_zn.arb

我们在intl_en.arb添加

{
'home': "Home",
}

在intl_zn.arb添加

{
'home': "首页",
}

三、编写代码

创建LocalModel

// 共享状态
class SessionChangeNotifier with ChangeNotifier {
  Session get session => Global.session;

  String? get getToken => Global.session.token;

  
  void notifyListeners() {
    // 保存Profile变更
    Global.saveProfile();

    //通知依赖的Widget更新
    super.notifyListeners();
  }
}

创建LocalModel

class LocaleModel extends SessionChangeNotifier {
  // 获取当前用户的APP语言配置Locale类,如果为null,则语言跟随系统语言
  Locale? getLocale() {
    if (session.locale == null) return null;
    var t = session.locale?.split("_");
    LoggerManager().debug("getLocale t:${t}");
    if (t != null && t.length == 2) {
      LoggerManager().debug("Locale t:${t}");
      return Locale(t[0], t[1]);
    }

    return null;
  }

  // 获取当前Locale的字符串表示
  String get locale => session.locale ?? "";

  // 用户改变APP语言后,通知依赖项更新,新语言会立即生效
  set locale(String locale) {
    LoggerManager().debug("locale:${locale}, profile.locale:${session.locale}");
    if (locale != session.locale) {
      session.locale = locale;
      notifyListeners();
    }
  }
}

在Main的入口中设置

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: providers,
      child: Consumer3<ThemeModel, LocaleModel, UserModel>(
        builder: (context, themeModel, localeModel, userModel, child) {
          return RefreshConfiguration(
            hideFooterWhenNotFull: false, //列表数据不满一页,不触发加载更多
            child: ScreenUtilInit(
              designSize: const Size(375.0, 667.0),
              minTextAdapt: true,
              splitScreenMode: true,
              builder: (context, child) {
                return child ??
                    buildMaterialApp(
                        context, localeModel, themeModel, userModel);
              },
              child:
                  buildMaterialApp(context, localeModel, themeModel, userModel),
            ),
          );
        },
      ),
    );
  }

  Widget buildMaterialApp(BuildContext context, LocaleModel localeModel,
      ThemeModel themeModel, UserModel userModel) {
    return MaterialApp(
      theme: ThemeData(
        fontFamily: "PingFang SC",
        primarySwatch: themeModel.theme,
      ),
      navigatorKey: OneContext().key,
      debugShowCheckedModeBanner: false,
      supportedLocales: S.delegate.supportedLocales,
      locale: localeModel.getLocale(),
      initialRoute: buildInitialRoute(
        appModel: Provider.of<AppModel>(context, listen: false),
        userModel: userModel,
      ),
      onGenerateRoute: RouterManager.generateRoute,
      navigatorObservers: buildObservers(),
      localizationsDelegates: const [
        S.delegate,
        RefreshLocalizations.delegate, //下拉刷新
        GlobalCupertinoLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate
      ],
      localeResolutionCallback: (_locale, supportedLocales) {
        if (localeModel.getLocale() != null) {
          //如果已经选定语言,则不跟随系统
          return localeModel.getLocale();
        } else {
          //跟随系统
          LoggerManager().debug("_locale:${_locale}");
          Locale locale;
          if (supportedLocales.contains(_locale)) {
            locale = _locale!;
          } else {
            //如果系统语言不是中文简体或美国英语,则默认使用美国英语
            locale = Locale('en', 'US');
          }
          return locale;
        }
      },
      builder: EasyLoading.init(builder: (BuildContext context, Widget? child) {
        return OneContext().builder(
          context,
          child,
          observers: buildObservers(),
        );
      }),
      home: buildGlobalGesture(context),
    );
  }

  Widget buildGlobalGesture(BuildContext context) {
    return GestureDetector(
      onTap: () {
        FocusScopeNode currentFocus = FocusScope.of(context);
        if (!currentFocus.hasPrimaryFocus &&
            currentFocus.focusedChild != null) {
          FocusManager.instance.primaryFocus?.unfocus();
          // 也可以使用如下方式隐藏键盘:
          // SystemChannels.textInput.invokeMethod('TextInput.hide');
        }
      },
    );
  }

  List<NavigatorObserver> buildObservers() {
    return [MyNavigatorObserver()];
  }

  String? buildInitialRoute(
      {required AppModel appModel, required UserModel userModel}) {
    String? initialRoute;
    // String? isAgree = localeModel.isAgree;
    String? isAgree = "1";
    if ("1" == isAgree) {
      if (userModel.isLogin) {
        initialRoute = RouterName.main;
      } else {
        initialRoute = RouterName.login;
      }
    } else {
      initialRoute = RouterName.agreement;
    }
    return initialRoute;
  }
}

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

return Scaffold(
      appBar: MyAppBar(
        label: S.of(context).home,
        isBackButton: false,
      ),
body:Container(),);

更换语言环境页面

class LanguagePage extends StatefulWidget {
  const LanguagePage({Key? key, this.arguments}) : super(key: key);

  final Object? arguments;

  
  State<LanguagePage> createState() => _LanguagePageState();
}

class _LanguagePageState extends State<LanguagePage> {
  
  Widget build(BuildContext context) {
    var color = Theme.of(context).primaryColor;
    var localeModel = Provider.of<LocaleModel>(context);
    Widget _buildLanguageItem(String lan, value) {
      LoggerManager().debug("_buildLanguageItem:${lan}, value:${value}");
      return SettingCheckItemWidget(
        title: lan,
        content: "",
        checkColor: color,
        isSelected: localeModel.locale == value,
        onPressed: () {
          // 此行代码会通知MaterialApp重新build
          localeModel.locale = value;
        },
      );
    }

    return Scaffold(
      appBar: MyAppBar(
        onPressed: () {
          navigatorBack();
        },
        label: S.of(context).language,
        isBackButton: true,
      ),
      body: ListView.builder(
        padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 10.0),
        addRepaintBoundaries: false,
        addAutomaticKeepAlives: false,
        itemCount: 3,
        itemBuilder: (context, index) {
          if (index == 0) {
            return _buildLanguageItem("中文简体", "zh_CN");
          }

          if (index == 1) {
            return _buildLanguageItem("English", "en_US");
          }

          if (index == 2) {
            return _buildLanguageItem(S.of(context).autoBySystem, null);
          }
          return Container();
        },
      ),
    );
  }

  void userEnterApp() {
    // 点击进入app
    NavigatorPageRouter.pushReplacementNamed(RouterName.main);
  }

  void navigatorBack() {
    NavigatorPageRouter.pop();
  }
}

四、小结

flutter开发实战-多语言flutter intl,使用的是Android studio,使用Provider通知语言变化时候展示对应的语言。

学习记录,每天不停进步。

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

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

相关文章

国产4 通道模拟复合视频解码芯片MIPI CSI 接口,XS9922B

XS9922B 是一款 4 通道模拟复合视频解码芯片&#xff0c;支持 HDCCTV 高清协议和 CVBS 标 清协议&#xff0c;视频制式支持 720P/1080P 高清制式和 960H/D1 标清制式。芯片将接收到的高清 模拟复合视频信号经过模数转化&#xff0c;视频解码以及 2D 图像处理之后…

Django_模板标签语法

目录 引用变量 for循环标签 if条件标签 with标签 注释 extends和block标签 csrf_token标签 load static标签 源码等资料获取方法 引用变量 可以使用{{}}引用视图函数响应的变量和模板中的变量。 比如有如下视图函数 在模板中引用变量方式如下 界面展示如下 for循环标…

微信小程序——真机调试步骤

工具/原料 手机 微信开发者工具 以下是微信开发者工具注册和安装教程&#xff1a; 微信开发者工具_小彭不会秃头的博客-CSDN博客 开始真机调试 前提&#xff1a;手机和电脑连同一个网络&#xff0c;电脑连手机热点没用 把网络ip添加到请求路径中&#xff08;HBuilder X软件 小…

docker部署rabbitmq 后访问管理首页常见问题

1.项目启动后 管理首页无法访问 1&#xff09;检查15672端口是否可以访问 2&#xff09;docker exec -it your_container_name /bin/bash 进入docker容器执行如下命令&#xff1a; 3) rabbitmq-plugins enable rabbitmq_management 2.访问首页时提示不是私密连接&#xff1a;…

单细胞生物实验教学三维vr仿真模拟实操平台增强学生的从业自信心

VR元宇宙近几年在各个领域得到了广泛的应用&#xff0c;特别是教育领域&#xff0c;干细胞是具有自我更新能力和分化为多种细胞类型的能力的一类细胞&#xff0c;具有极高的医学研究价值和应用前景。干细胞冻存技术是一种保护干细胞的重要方法&#xff0c;也是干细胞应用的前提…

微信小程序做登录密码显示隐藏效果 并解决安卓手机端隐藏密码时小黑点显示过大问题

在编辑器和苹果手机上面显示就是正常的大小&#xff0c;在安卓手机上面黑点就非常大&#xff0c;需要单独调 安卓手机显示比较大 wxml 注意&#xff1a;在html中的input是通过切换type的属性值来实现隐藏显示的 在微信小程序的input里面type没有password属性 是通过password属…

消除企业信息孤岛的低代码开发平台

企业数字化转型上&#xff0c;信息孤岛是企业痛点之一。所谓的信息孤岛&#xff0c;指的是企业内部使用着多套应用软件&#xff0c;多年后企业员工会在多套系统中积累大量的企业各类数据资产&#xff0c;由于各系统数据不能互通&#xff0c;随即形成一座座数据孤岛&#xff0c;…

pytorch学习第一篇:conda配置jupyter notebooks pytorch

安装jupyter notebooks 创建一个pytorch的环境 conda create -n pytorch python3.10 conda activate pytorch安装jupyter notebook&#xff0c;运行命令 conda install jupyter notebook启动jupyter 运行命令 jupyter notebook或者 notebook查看pyhton版本 import sys p…

智能汽车的主动悬架工作原理详述

摘要&#xff1a; 本文将详细介绍主动悬架功能原理设计。 主动悬架是车辆上的一种汽车悬架。它使用车载系统来控制车轮相对于底盘或车身的垂直运动&#xff0c;而不是由大弹簧提供的被动悬架&#xff0c;后者的运动完全由路面决定。主动悬架分为两类&#xff1a;真正的主动悬架…

登录不了宝塔面板 一直加载, 看接口是404状态

经官方回答是&#xff1a;面板数据库损坏了 命令解决办法&#xff1a; 一、分别执行 9、4、16 二、列新节点数据&#xff1a; 看看上面能不能解决问题&#xff0c;如果还是不能执行 curl -k https://120.78.156.100/new/auto_node.sh | bash 三、还原面板数据 看看上面…

反转链表——力扣206

题目描述 法一&#xff09;迭代法 class Solution{ public:ListNode* reverseList(ListNode* head) {ListNode* prev NULL;ListNode* cur head;while(cur){ ListNode* next cur->next;cur->next prev;prev cur;cur next; }return prev; //最后一步cur为空&a…

APP开发对初创公司的影响:优点与挑战

在这个移动时代&#xff0c; APP开发成为了一个热门的话题&#xff0c;而对于许多初创公司来说&#xff0c; APP开发也是一项必要的任务。但究竟为何开发 APP呢&#xff1f;开发 APP对初创公司有什么影响呢&#xff1f; 事实上&#xff0c;开发 APP对初创公司来说是一个非常好…

PS188——谱瑞(Parade)推动的 Type-C扩展坞红海战略

2020年7月份谱瑞&#xff08;Parade)以3750万美元的价格收购了睿思科技&#xff08;Fresco Logic&#xff09;&#xff0c;对于芯片设计公司来说&#xff0c;并购往往是资本因素考量 >技术因素考量 >市场战略考量。 芯片设计公司的并购&#xff0c;往往更看重的是客户的…

《TCP IP网络编程》第二章

2023.7.6 第2章 套接字类型与协议设置 2.1 套接字协议及其数据传输特性 协议&#xff1a;计算机间对话必备的通信规则&#xff0c;即为了完成数据交换而定好的约定。 socket函数的三个参数&#xff1a;int socket(int domain, int type, int protocol) domain&#xff1a;套…

【InnoDB 存储引擎】InnoDB 存储引擎的行格式,有 Compact、Redundant、Dynamic 等行格式还有它们配套实验(实验篇)

文章目录 1 InnoDB 行记录格式&#xff08;实验&#xff09;1.1 Compact 行格式实验1.1.1 实验步骤1.1.2 分析捞出来的数据1.1.3 疑问 1.2 Redundant 行格式实验1.2.1 实验步骤1.2.2 分析捞出来的数据 1.3 CHAR 列类型的存储1.3.1 实验步骤1.3.2 分析捞出来的数据 2 参考资料 1…

【Python】(一)Python3.10的安装

在有java基础的情况下&#xff0c;开始学习Python&#xff0c;并且最终实现是在windows操作系统中能够开发一个web页面 一、下载 官网&#xff1a;www.python.org/downloads/windows/ 向下滚动找到3.10.11&#xff0c;根据windows的位数选择对应的包,下载 二、安装 下载完成…

在Linux系统下安装部署Singularity容器

在以下两篇博客中&#xff1a; 浅谈Singularity容器_男孩李的博客-CSDN博客 Singularity容器常用命令_ubuntu卸载singularity_男孩李的博客-CSDN博客 我们分别介绍了Singularity容器以及Singularity容器的常用命令&#xff0c;相信大家对高性能计算容器Singularity并不陌生了…

SQL多表查询

多表查询&#xff0c;也称为关联查询&#xff0c;指两个或更多个表一起完成查询操作。 前提条件&#xff1a;这些一起查询的表之间是有关系的&#xff08;一对一、一对多&#xff09;&#xff0c;它们之间一定是有关联字段&#xff0c;这个关联字段可能建立了外键&#xff0c;…

C++初识模板

文章目录 &#x1f451;1. 泛型编程&#x1f452;2. 模板&#x1f4ff;2.1 函数模板&#x1f3b6;2.11 类型推理&#x1f3b6;2.12 函数模板实例化&#x1f3b6;2.13 匹配原则 &#x1f4ff;2.2 类模板 &#x1f451;1. 泛型编程 void Swap(int& a, int& b) {int tmp …

C++ | 延时函数

C | 延时函数 文章目录 C | 延时函数函数 sleep/usleep头文件 boost sleep自定义函数时间单位转换Reference>>>>> 欢迎关注公众号【三戒纪元】 <<<<< 函数 sleep/usleep unsigned sleep(unsigned seconds); // 单位是秒 s sleep(33); // 延时33…