flutter开发实战-多语言flutter intl

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通知语言变化时候展示对应的语言。

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

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

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

相关文章

Django_自定义文件存储类并将图片上传到FastDFS

目录 将图片到FastDFS和浏览的流程图 使用自定义文件存储类 1、定义存储类 2、创建FastDFS的配置文件 3、修改settings.py配置 4、上传图片进行验证 4.1 定义一个包含ImageField字段的模型类 4.2 登录django的admin后台 4.3 上传图片 4.4 查看图片 源码等资料获取方…

webrtc源码阅读之视频RTP接收JitterBuffer

在音视频通信中&#xff0c;网络抖动和延迟是常见的问题&#xff0c;会导致音视频质量下降和用户体验不佳。为了解决这些问题&#xff0c;WebRTC引入了Jitter Buffer&#xff08;抖动缓冲区&#xff09;这一重要组件。Jitter Buffer是一个缓冲区&#xff0c;用于接收和处理网络…

树与图的(深度 + 广度)优先遍历

目录 一、树与图的存储1.树的特性2.图的分类3.有向图的储存结构 二、树与图的深度优先遍历的运用树的重心题意分析代码实现 三、树与图的广度优先遍历的运用图中点的层次题意分析代码实现 一、树与图的存储 1.树的特性 树是一种特殊的图,具有以下两个重要特性: 无环 树是一个…

7.Java 运算符

运算符分成以下几组 算术运算符关系运算符位运算符逻辑运算符赋值运算符其他运算符 1.算术运算符 public class Test {public static void main(String[] args) {int a 10;int b 20;int c 25;int d 25;System.out.println("a b " (a b) );System.out.print…

奥威BI-金蝶云星空SaaS版一站式平台:对接数据、做分析

金蝶云星空和BI大数据分析平台都在企业数字化转型中扮演了重要的角色&#xff0c;为企业提供了全面的数字化解决方案和数据分析功能&#xff0c;两者强强联合不仅能提高部署效率&#xff0c;更能增强数据分析、数据可视化效果&#xff0c;帮助企业更好地适应市场变化和用户需求…

基于SSM的新生报到系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Interactive Image Segmentation

Focused and Collaborative Feedback Integration for Interactive Image Segmentation CVPR 2023 清华 Interactive image segmentation aims at obtaining a segmentation mask for an image using simple user annotations. During each round of interaction, the segment…

科技资讯|苹果Vision Pro预计2024年末全球发售

据彭博社记者古尔曼消息&#xff0c;苹果首款头显Vision Pro计划于2024年初在美国市场指定店铺进行开售&#xff0c;这些商店将会有专属区域用于产品演示&#xff0c;配备座位、配件和测量尺寸的工具等。知情人士透露&#xff0c;将有270家美国的苹果商店会销售Vision Pro&…

基于JSP+Servlet的医药药品管理系统

用户类型&#xff1a;双角色角色&#xff08;患者、管理员[医生]&#xff09; 设计模式&#xff1a;MVC&#xff08;jspservletjavabean) 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 主要技术&#xff1a;jsp、servlet、jdbc、jsp、html5、jquery、css、js…

小程序项目时间选择器用法

项目需求是要实现这种形式, 但是相信大家都试了各种插件,都不太合适,uView框架也不能满足自己的需要; 推荐使用:uview-ui-plus 基本上小程序遇到的单选多选 日期 省市区 都可以完美的实现,可以通过插件市场安装使用 但是要实现ui给的原型图 还需要做一下调整 弹性布局给两个选…

【Linux】1、装机、装操作系统、部署

文章目录 一、装系统1.0 格式化 U 盘1.1 做启动盘1.1.2 rufus1.1.2 poweriso 1.2 安装步骤 二、恢复系统2.1 BootManager2.2 recovery mode 一、装系统 下载地址&#xff1a; http://old-releases.ubuntu.com/releases/16.04.5/ubuntu-16.04.5-server-amd64.isohttps://mirro…

C#内存不够解决方法

今天在使用C#程序的时候&#xff0c;出现了下图的问题&#xff1a; 注意下图中我用红框标出的位置&#xff0c;实际是一个三维数组。 但是出现这个问题和三维数组没有关系。 他是提示内存不足。 百度了一下&#xff0c;C#在生成的过程中如果是生成对应的32位系统&#xff0c…

C国演义 [第九章]

第九章 买卖股票的最佳时机III题目理解步骤dp数组递推公式初始化遍历方向 代码 买卖股票的最佳时机IV题目理解步骤dp数组递推公式初始化遍历方向 代码 买卖股票的最佳时机III 力扣链接 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格 设计一个算法…

制作Visual Studio离线安装包

vs2015之后官网就不提供离线安装包了&#xff0c;使用离线安装包就需要自己手动制作一个&#xff1b; 以vs2019为例&#xff1a; 先去官网下载在线安装器 官网下载地址&#xff1a;Visual Studio 较旧的下载 - 2019、2017、2015 和以前的版本 (microsoft.com) 展开2019的标签…

2023.7.15

同余最短路 P3403 跳楼机 题意&#xff1a;给定h高的楼层&#xff0c;起始位置在第一层&#xff0c;可以选择操作向上移动x层或y层或z层&#xff0c;回到第一层 求可以到达的楼层数 思路&#xff1a;转化题意为求axbyczk(k在[1,h]&#xff0c;x,y,z为正整数,有多少k满足条件&am…

推荐一款IDEA神级插件【Bito】而且免费!

什么是Bito&#xff1f; Bito是一款在IntelliJ IDEA编辑器中的插件&#xff0c;Bito插件是由ChatGPT团队开发的&#xff0c;它是ChatGPT团队为了提高开发效率而开发的一款工具。ChatGPT团队是一支专注于自然语言处理技术的团队&#xff0c;他们开发了一款基于GPT的自然语言处理…

动态规划之118杨辉三角(第6道)

题目&#xff1a;给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 题目链接&#xff1a;118. 杨辉三角 - 力扣&#xff08;LeetCode&#xff09; 示例&#xff1a; 解法&#xff1…

C/C++实现高并发http服务器

http高并发服务器实现 基础知识 html&#xff0c;全称为html markup language&#xff0c;超文本标记语言。 http&#xff0c;全称hyper text transfer protocol&#xff0c;超文本传输协议。用于从万维网&#xff08;WWW&#xff1a;World Wide Web&#xff09;服务器传输超…

异地使用PLSQL远程连接访问Oracle数据库【内网穿透】

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 转载自cpolar极点云文章&#xff1a;公网远程连接…

Jenkins的几种安装方式以及邮件配置

目录 Jenkins介绍 Jenkins下载、安装 一、通过war包安装 二、通过docker安装 jenkins 容器中添加 git, maven 等组件 jenkins 容器中的公钥私钥 在 jenkins 容器中调用 docker 简单的方式启动 Docker server REST API 一个 jenkins 示例 三、通过Homebrew安装 访问Je…