Flutter 应用服务:主题、暗黑、国际化、本地化-app_service库

Flutter应用服务
主题、暗黑、国际化、本地化-app_service库

作者李俊才 (jcLee95):https://blog.csdn.net/qq_28550263
邮箱 :291148484@163.com
本文地址:https://blog.csdn.net/qq_28550263/article/details/135903762
模块地址:https://pub.dev/packages/app_service
国内镜像:https://pub-web.flutter-io.cn/packages/app_service


在这里插入图片描述


1. 概述

在Flutter中,我们通常通过构建服务来实现贯穿整个应用生命周期的状态管理。例如,在实现用户认证功能时,可以创建一个Auth服务。类似地,还有许多其他场景,比如应用主题管理。对于主题、暗黑模式、国际化与本地化等场景,通常会实现一个AppService来集中管理这些方面。App Service库提供了一套全面的应用管理服务,同时提供了相关的UI组件和持久化解决方案。

App Service 是一个基于 GetX 的应用服务,提供应用级别的管理服务,如主题管理、深色模式管理和本地化管理。

在这里插入图片描述

2. 安装

你可以使用flutter pub add命令在你的项目中安装App Service的最新版本:

flutter pub add app_seivice

这将在项目的pubspec.yaml文件的 dependencies字段中添加app_seivice作为依赖,并隐式地运行一次flutter pub get

3. 用法实践

3.1 在依赖注入中管理 App Service

在实际项目中,除了 AppService 外,可能还有许多其他需要管理的依赖项,因此我喜欢创建一个 injections.dart 文件来描述这些依赖项。
以下示例使用 GetIt 库来管理依赖项。您还可以根据自己的习惯使用其他依赖管理方案。

import 'package:app_service/app_service.dart';
import 'package:get_it/get_it.dart';/// 基于 Get it 库的依赖注入
class GetitInjection {static void init() {final GetIt i = GetIt.instance;AppService appService = AppService(supportedLanguages: const [LanguageEnum.zh,LanguageEnum.en,],defaultLang: LanguageEnum.zh,);i.registerLazySingleton<AppService>(() => appService); }
}

3.2 主题管理

应用服务中的主题管理用于切换不同的颜色主题,每个主题包含两种模式,即深色模式和浅色模式。
库中内置了由 flex_color_scheme 生成的许多主题数据。

以下是内置主题表:

主题名称(中文)亮色主题暗色主题
琥珀蓝amberBlueLightThemeamberBlueDarkTheme
青蓝aquaBlueLightThemeaquaBlueDarkTheme
巴哈马特立尼达bahamaTrinidadLightThemebahamaTrinidadDarkTheme
巴罗萨barossaLightThemebarossaDarkTheme
大石郁金香bigStoneTulipLightThemebigStoneTulipDarkTheme
蓝色的欢愉blueDelightLightThemeblueDelightDarkTheme
蓝石青blueStoneTealLightThemeblueStoneTealDarkTheme
蓝鲸blueWhaleLightThemeblueWhaleDarkTheme
布卢曼blumineLightThemeblumineDarkTheme
品牌蓝brandBlueLightThemebrandBlueDarkTheme
棕橙brownOrangeLightThemebrownOrangeDarkTheme
卡玛龙绿camaroneGreenLightThemecamaroneGreenDarkTheme
丝绒和月亮damaskLunarLightThemedamaskLunarDarkTheme
深蓝海deepBlueSeaLightThemedeepBlueSeaDarkTheme
深紫deepPurpleLightThemedeepPurpleDarkTheme
戴尔热那亚绿dellGenoaGreenLightThemedellGenoaGreenDarkTheme
乌木粘土ebonyClayLightThemeebonyClayDarkTheme
茄子紫eggplantPurpleLightThemeeggplantPurpleDarkTheme
企业家蓝endeavourBlueLightThemeendeavourBlueDarkTheme
浓缩咖啡奶油espressoCremaLightThemeespressoCremaDarkTheme
Flutter DashflutterDashLightThemeflutterDashDarkTheme
金黄日落goldSunsetLightThemegoldSunsetDarkTheme
绿greensLightThemegreensDarkTheme
绿色森林greenForestLightThemegreenForestDarkTheme
绿色丛林greenJungleLightThemegreenJungleDarkTheme
绿钱greenMoneyLightThemegreenMoneyDarkTheme
灰色法律greyLawLightThemegreyLawDarkTheme
嬉皮蓝hippieBlueLightThemehippieBlueDarkTheme
靛蓝之夜indigoNightLightThemeindigoNightDarkTheme
靛蓝圣马力诺indigoSanMarinoLightThemeindigoSanMarinoDarkTheme
唇膏粉lipstickPinkLightThemelipstickPinkDarkTheme
野鸭瓦伦西亚mallardValenciaLightThememallardValenciaDarkTheme
芒果莫吉托mangoMojitoLightThememangoMojitoDarkTheme
material3material3LightThemematerial3DarkTheme
Material3 高对比material3HighContrastLightThemematerial3HighContrastDarkTheme
Material3 紫色material3PurpleLightThemematerial3PurpleDarkTheme
午夜midnightLightThememidnightDarkTheme
清真寺青mosqueCyanLightThememosqueCyanDarkTheme
哦曼迪红ohMandyRedLightThemeohMandyRedDarkTheme
外太空舞台outerSpaceLightThemeouterSpaceDarkTheme
粉红樱花pinkSakuraLightThemepinkSakuraDarkTheme
紫褐purpleBrownLightThemepurpleBrownDarkTheme
红蓝redBlueLightThemeredBlueDarkTheme
红色龙卷风redTornadoLightThemeredTornadoDarkTheme
红酒redWineLightThemeredWineDarkTheme
红木rosewoodLightThemerosewoodDarkTheme
锈橙色rustDeepOrangeLightThemerustDeepOrangeDarkTheme
圣胡安蓝sanJuanBlueLightThemesanJuanBlueDarkTheme
鲨鱼橙sharkOrangeLightThemesharkOrangeDarkTheme
雷鸟红thunderbirdRedLightThemethunderbirdRedDarkTheme
威尔敦绿verdunGreenLightThemeverdunGreenDarkTheme
威尔敦酸橙verdunLimeLightThemeverdunLimeDarkTheme
尼古拉斯烧焦vesuviusBurnedLightThemevesuviusBurnedDarkTheme
柳树芥末willowWasabiLightThemewillowWasabiDarkTheme
育空金黄yukonGoldYellowLightThemeyukonGoldYellowDarkTheme

要切换主题,你可以使用AppService实例对象的setColorTheme对主题进行切换,该方法的类型签名为:

void setColorTheme(ColorThemesEnum themeEnum)

例如:

// 获取 AppService 实例
final AppService appService = GetIt.instance.get<AppService>();// 切换主题为 bigStoneTulip
appService.setColorTheme(ColorThemesEnum.bigStoneTulip);

你可以使用ThemeModal模态框组件来为用户提供更加直观的主题选择,例如:

const ThemeModal(),

它以一个主题图标的形式显示在页面上:

在这里插入图片描述

如果触摸或点击该图标,将会以对话框的形式为用户提供主题选择:

在这里插入图片描述

每一个主题将以其primaryColor色的圆形显示在该模态框中,被选中的主题对应的圆形有一个“√”号。

3.2 暗黑模式管理

App Service 库中,Dark/Light 模式是同一主题下的两个子状态,本质上是定义了两组对应的主题数据。你可以直接在AppSeivice的单例中,通过 toggleDarkMode 方法切换暗黑模式:

// 获取 AppService 单例
final AppService appService = GetIt.instance.get<AppService>();
// 切换暗黑模式
appService.toggleDarkMode()

另外,实例对象appService上,用于设置暗黑/光亮的方法还有setDarkModesetLightMode

DarkModeSwitch 是一个可以直接使用的暗黑模式切换开关,你可以直接在代码中使用它。外观上,它看起来就像这样:

在这里插入图片描述

3.3 国际化和本地化管理

Messages是一个翻译容器,它接受一个列表,可以用来包含多个翻译。其类型签名为:

Messages Messages(List<Map<String, Map<String, String>>> translations
)

你应该在顶级组件 GetMaterialApp 中通过translations参数传入它,并且必须在列表中包含一个AppServiceMessages().keys,这是一份用于App Service的翻译文件。例如:

GetMaterialApp(translations: Messages([AppServiceMessages().keys,// 其它翻译HomeMessages().keys,]),
);

其中,HomeMessages是一个假定的自定义翻译文件,它看起来像这样:

import 'package:get/get.dart';class HomeMessages extends Translations {Map<String, Map<String, String>> get keys => {'zh_CN': {'home.appService_demo': 'AppService 演示',},'en': {'home.appService_demo': 'AppService Demo',},'ko_KR': {'home.appService_demo': 'AppService 데모',},'ja_JP': {'home.appService_demo': 'AppService デモ',},// More language translate...};
}

当然,依据项目的需要你可以定义更多这样的翻译文件,并在Messagestranslations列表中加载。

实现国际化时,定义支持的多种语言是通过构造AppServicesupportedLanguages参数指定的,它接受由多个LanguageEnum 枚举值所构成的列表。AppService还需要指定一个默认的语言。例如:

AppService appService = AppService(supportedLanguages: const [LanguageEnum.zh,LanguageEnum.en,LanguageEnum.fr,],defaultLang: LanguageEnum.zh,
);

其中,defaultLang的默认值为 LanguageEnum.en。这里的定义需要与顶层组件中的locale参数对应。

应用标题是不能使用GetX提供的.tr来实现翻译的,因为在顶层组件初始化完成之前该方法不可用。这在 Web 端的本地化切换效果尤为明显:

在这里插入图片描述

为了实现这种动态切换,你可以像我一样使用一个switch语句,下面是一个示例:

import 'package:app_service/app_service.dart';// ...
GetMaterialApp(// ...title: switch (Get.locale?.languageCode) {'zh' => 'AppService 演示','en' => 'AppService Demo','fr' => 'AppService démonstration','ja' => 'AppServiceデモ','ko' => 'App 서비스 데모','ar' => 'تطبيق AppService',_ => 'AppService Demo',},translations: Messages([AppServiceMessages().keys,HomeMessages().keys,]),locale: const Locale('zh', 'CN'),fallbackLocale: const Locale('en', 'US'),home: const HomeView(),
);

要切换语言,可以使用AppService实例对象上的updateLocale方法,该方法的类型签名为:

void updateLocale(LanguageEnum newLanguage)

例如:

appService.updateLocale(LanguageEnum.zh);

有两个组件可以用于显示一个语言选择菜单以切换本地语言,分别是LangSelectMenuWen

其中,LangSelectMenu是一个普通的方形下拉按钮,例如:

const LangSelectMenu(),

看起来像这样:

在这里插入图片描述

Wen也是一个弹出菜单的按钮,只不过它以一个图标显示,这通常同于Header中:

const Wen()

看起来就像这样:

在这里插入图片描述

你可以自定义显示的图标,以及图标的大小,并且它可以是任何组件。

4. 服务初始化

初始化用于从持久化的数据中读取用户上一次存储的数据。在AppService 实例上提供了一个init方法用于完成其自身的相关初始化工作。

在你的应用中,可以使用多种方式完成初始化,例如,下面的代码展示了通过顶层组件GetMaterialApponInit方法实现初始化:

// ...
void main() async {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Future<void> onInit(BuildContext context) async {// Init AppServicefinal appService = GetIt.instance.get<AppService>();await appService.init();// ...Other initializations}Widget build(BuildContext context) {final appService = GetIt.instance.get<AppService>();return GetMaterialApp(// ...onInit: () async {await onInit(context);},);}
}

5. Web App

在 Web App 中,当前的 sharedPreferencesWeb 库通过 localStorage 实现键值对存储。如果改变 AppService 所管理的相关状态,这些变化将直接反映在浏览器的 localStorage 中:

在这里插入图片描述

6. 示例应用

你可以在https://github.com/jacklee1995/flutter_app_service/tree/master/example中找到 App Service 的示例应用。

F. 附录

About version

各个版本所依赖的 GetX 推荐版本如下表所示:

App ServiceGetX
1.0.04.6

版本相差不大都可以通用。

Enums

LanguageEnum
/// 枚举表示不同的语言代码。
enum LanguageEnum {zh, // 中文(zhHans, // 中文(简体)zhHant, // 中文(繁体)zhHk, // 中文(香港)zhTw, // 中文(台湾)ru, // 俄语de, // 德语fr, // 法语ja, // 日语ko, // 韩语es, // 西班牙语ar, // 阿拉伯语en, // 英语enUs, // 英语(美国)enUk, // 英语(英国)pt, // 葡萄牙语it, // 意大利语nl, // 荷兰语tr, // 土耳其语hi, // 印地语id, // 印尼语vi, // 越南语th, // 泰语ms, // 马来语fil, // 菲律宾语sv, // 瑞典语pl, // 波兰语hu, // 匈牙利语ro, // 罗马尼亚语cs, // 捷克语el, // 希腊语he, // 希伯来语da, // 丹麦语fi, // 芬兰语no, // 挪威语sk, // 斯洛伐克语sl, // 斯洛文尼亚语bg, // 保加利亚语af, // 南非荷兰语sq, // 阿尔巴尼亚语hy, // 亚美尼亚语az, // 阿塞拜疆语eu, // 巴斯克语bn, // 孟加拉语bs, // 波斯尼亚语ca, // 加泰罗尼亚语hr, // 克罗地亚语cy, // 威尔士语et, // 爱沙尼亚语tl, // 菲律宾语gl, // 加利西亚语ka, // 格鲁吉亚语gu, // 古吉拉特语ht, // 海地克里奥尔语ha, // 豪萨语haw, // 夏威夷语iw, // 希伯来语jw, // 爪哇语kk, // 哈萨克语km, // 高棉语kn, // 卡纳达语ky, // 吉尔吉斯语lo, // 老挝语la, // 拉丁语lv, // 拉脱维亚语lt, // 立陶宛语lb, // 卢森堡语mk, // 马其顿语mg, // 马尔加什语mt, // 马耳他语mi, // 毛利语mr, // 马拉地语mn, // 蒙古语ne, // 尼泊尔语ps, // 普什图语pa, // 旁遮普语qu, // 凯楚亚语gd, // 苏格兰盖尔语sr, // 塞尔维亚语st, // 塞索托语sn, // 修纳语sd, // 信德语si, // 僧伽罗语su, // 巽他语sw, // 斯瓦希里语tg, // 塔吉克语ta, // 泰米尔语te, // 泰卢固语ur, // 乌尔都语uz, // 乌兹别克语xh, // 科萨语yi, // 意第绪语zu, // 祖鲁语
}
ColorThemesEnum
/// 主题颜色的枚举,包括了每个主题的名称。
enum ColorThemesEnum {/// 琥珀蓝amberBlue,/// 青蓝aquaBlue,/// 巴哈马特立尼达bahamaTrinidad,/// 巴罗萨barossa,/// 大石郁金香bigStoneTulip,/// 蓝色的欢愉blueDelight,/// 蓝石青blueStoneTeal,/// 蓝鲸blueWhale,/// 布卢曼blumine,/// 品牌蓝brandBlue,/// 棕橙brownOrange,/// 卡玛龙绿camaroneGreen,/// 丝绒和月亮damaskLunar,/// 深蓝海deepBlueSea,/// 深紫deepPurple,/// 戴尔热那亚绿dellGenoaGreen,/// 乌木粘土ebonyClay,/// 茄子紫eggplantPurple,/// 企业家蓝endeavourBlue,/// 浓缩咖啡奶油espressoCrema,/// Flutter DashflutterDash,/// 金黄日落goldSunset,/// 绿greens,/// 绿色森林greenForest,/// 绿色丛林greenJungle,/// 绿钱greenMoney,/// 灰色法律greyLaw,/// 嬉皮蓝hippieBlue,/// 靛蓝之夜indigoNight,/// 靛蓝圣马力诺indigoSanMarino,/// 唇膏粉lipstickPink,/// 野鸭瓦伦西亚mallardValencia,/// 芒果莫吉托mangoMojito,/// Material3material3,/// Material3 高对比material3HighContrast,/// Material3 紫色material3Purple,/// 午夜midnight,/// 清真寺青mosqueCyan,/// 哦曼迪红ohMandyRed,/// 外太空舞台outerSpace,/// 粉红樱花pinkSakura,/// 紫褐purpleBrown,/// 红蓝redBlue,/// 红色龙卷风redTornado,/// 红酒redWine,/// 红木rosewood,/// 锈橙色rustDeepOrange,/// 圣胡安蓝sanJuanBlue,/// 鲨鱼橙sharkOrange,/// 雷鸟红thunderbirdRed,/// 威尔敦绿verdunGreen,/// 威尔敦酸橙verdunLime,/// 尼古拉斯烧焦vesuviusBurned,/// 柳树芥末willowWasabi,/// 育空金黄yukonGoldYellow,
}
工具
语言相关
/// 将语言枚举值转换为字符串
String? langEnumToStr(LanguageEnum lang)
/// 将语言标志转换为相应的国家标志
String getCountryCode(String item)
/// 将语言字符串转换为相应的语言枚举
LanguageEnum? strToLangEnum(String langStr)
主题相关
/// 将颜色主题与深色模式组合,并返回相应的 ThemeData 对象。
/// - themeName: 主题的名称。
/// - isDarkMode: 是否使用深色模式。
ThemeData getThemeDataByName(String themeName, bool isDarkMode)
/// 根据枚举获取主题数据 (ThemeData)。
ThemeData getThemeDataByEnum(ColorThemesEnum themeEnum, bool isDarkMode)

报告错误

你可以在 Github 上报告错误:https://github.com/jacklee1995/flutter_app_service/issues

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务-微服务Alibaba-Nacos 源码分析(上)

Nacos&Ribbon&Feign核心微服务架构图 架构原理 1、微服务系统在启动时将自己注册到服务注册中心&#xff0c;同时外发布 Http 接口供其它系统调用(一般都是基于Spring MVC) 2、服务消费者基于 Feign 调用服务提供者对外发布的接口&#xff0c;先对调用的本地接口加上…

Java 面试题之 IO(二)

字符流 文章目录 字符流Reader&#xff08;字符输入流&#xff09;Writer&#xff08;字符输出流&#xff09; 文章来自Java Guide 用于学习如有侵权&#xff0c;立即删除 不管是文件读写还是网络发送接收&#xff0c;信息的最小存储单元都是字节。 那为什么 I/O 流操作要分为字…

seata 分布式

一、下载安装seata 已经下载好的朋友可以跳过这个步骤。这里下载的是seata1.6.1这个版本。 1、进入seata官网 地址&#xff1a; https://seata.io/zh-cn/index.html 2、进入下载 3、点击下载地址 下载地址&#xff1a; https://github.com/seata/seata 二、配置seata 进入c…

如何在群晖NAS部署office服务实现多人远程协同办公编辑文档

文章目录 本教程解决的问题是&#xff1a;1. 本地环境配置2. 制作本地分享链接3. 制作公网访问链接4. 公网ip地址访问您的分享相册5. 制作固定公网访问链接 本教程解决的问题是&#xff1a; 1.Word&#xff0c;PPT&#xff0c;Excel等重要文件存在本地环境&#xff0c;如何在编…

如何使用保留可探测字段参数的方法解决视频监控管理平台EasyCVR无法启动的问题

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

费一凡:土木博士的自我救赎之道 | 提升之路系列(五)

导读 为了发挥清华大学多学科优势&#xff0c;搭建跨学科交叉融合平台&#xff0c;创新跨学科交叉培养模式&#xff0c;培养具有大数据思维和应用创新的“π”型人才&#xff0c;由清华大学研究生院、清华大学大数据研究中心及相关院系共同设计组织的“清华大学大数据能力提升项…

幻兽帕鲁服务器一键部署保姆教程

在帕鲁的世界&#xff0c;你可以选择与神奇的生物「帕鲁」一同享受悠闲的生活&#xff0c;也可以投身于与偷猎者进行生死搏斗的冒险。帕鲁可以进行战斗、繁殖、协助你做农活&#xff0c;也可以为你在工厂工作。你也可以将它们进行售卖&#xff0c;或肢解后食用。 想要部署属于自…

防御保护 笔记整理

一、ASPF--- 针对应用层的包过滤 ASPF --- 针对应用层的包过滤 --- 用来抓取多通道协议中协商端口的关键数据包&#xff0c;之后&#xff0c;将端 口算出&#xff0c;将结果记录在sever-map表中&#xff0c;相当于开辟了一条隐形的通道。 FTP --- 文件传输协议 FTP协议是一个典…

RabbitMQ基本使用,docker安装RabbitMQ,SpringBoot整合RabbitMQ

1.拉取镜像 docker pull rabbitmq:3.9.15-management2.运行容器 docker run -d --hostname rabbit1 --name myrabbit1 -p 15672:15672 -p 5672:5672 -e RABBITMQ_ERLANG_COOKIErabbitcookie rabbitmq:3.9.15-management3.访问地址 安装ip加端口号 http://192.168.123.3:156…

(九)springboot实战——springboot3下的webflux项目参数验证及其全局参数验证异常处理

前言 在上一节内容中&#xff0c;我们介绍了如何在webflux项目中自定义实现一个全局的异常处理器ErrorWebExceptionHandler&#xff0c;正常情况下其可以处理我们系统的运行时异常&#xff0c;但是无法处理参数验证的异常WebExchangeBindException&#xff0c;所以这里提供另外…

防火墙到防火墙的高可用知识汇总

目录​​​​​​​ 防火墙 防火墙的分类&#xff1a; 防火墙的发展史 传统防火墙&#xff08;包过滤防火墙&#xff09;—— 一个严格的规则表 传统防火墙&#xff08;应用代理防火墙&#xff09;—— 每个应用添加代理 传统防火墙&#xff08;状态检测防火墙&#xff09…

宝塔控制面板配置SSL证书实现网站HTTPS

宝塔安装SSL证书提前申请好SSL证书&#xff0c;如果还没有&#xff0c;先去Gworg里面申请&#xff0c;一般几分钟就可以下来&#xff0c;申请地址&#xff1a;首页-Gworg官方店-淘宝网 一、登录邮箱下载&#xff1a;Gworg证书文件目录 &#xff0c;都会有以下五个文件夹。宝塔…