Flutter应用服务插件app_service的使用
Flutter应用服务插件app_service的使用
1. 获取开始指南
你可以通过以下命令在项目中安装最新版本的App Service:
flutter pub add app_service
这将在你的项目的pubspec.yaml文件的dependencies字段中添加app_service作为依赖项,并隐式运行flutter pub get。
2. 在依赖注入中管理App Service
在实际项目中,除了AppService外,可能还需要管理许多其他依赖项。因此,我喜欢创建一个injections.dart文件来描述这些依赖项。以下示例使用了Get库来管理依赖项。
import 'package:app_service/app_service.dart';
import 'package:get/instance_manager.dart';
import 'package:shared_preferences/shared_preferences.dart';
Future<void> initDependencies() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
Get.put<SharedPreferences>(prefs);
// 应用管理
Get.lazyPut<AppService>(
() => AppService(
Get.find<SharedPreferences>(),
supportedLanguages: const [
LanguageEnum.zh,
LanguageEnum.zhHk,
LanguageEnum.zhMO,
LanguageEnum.zhTW,
LanguageEnum.en,
LanguageEnum.enUK,
LanguageEnum.enUS,
LanguageEnum.de,
LanguageEnum.ru,
LanguageEnum.uk,
LanguageEnum.be,
LanguageEnum.kk,
LanguageEnum.sr,
LanguageEnum.fr,
LanguageEnum.ja,
LanguageEnum.ko,
LanguageEnum.ar,
],
),
fenix: true,
);
}
在旧版本中,你需要使用defaultLang: LanguageEnum.zh,配置默认语言。目前,列表中的第一个配置作为默认值。
2.1 主题管理
主题管理用于在不同的颜色主题之间切换,每个主题包括两种模式:深色模式和浅色模式。该库包含了许多由flex_color_scheme生成的内置主题数据。
以下是内置主题的表格:
| 主题名称 | 浅色主题 | 深色主题 |
|---|---|---|
| amberBlue | amberBlueLightTheme | amberBlueDarkTheme |
| aquaBlue | aquaBlueLightTheme | aquaBlueDarkTheme |
| bahamaTrinidad | bahamaTrinidadLightTheme | bahamaTrinidadDarkTheme |
| barossa | barossaLightTheme | barossaDarkTheme |
| bigStoneTulip | bigStoneTulipLightTheme | bigStoneTulipDarkTheme |
| blueDelight | blueDelightLightTheme | blueDelightDarkTheme |
| blueStoneTeal | blueStoneTealLightTheme | blueStoneTealDarkTheme |
| blueWhale | blueWhaleLightTheme | blueWhaleDarkTheme |
| blumine | blumineLightTheme | blumineDarkTheme |
| brandBlue | brandBlueLightTheme | brandBlueDarkTheme |
| brownOrange | brownOrangeLightTheme | brownOrangeDarkTheme |
| camaroneGreen | camaroneGreenLightTheme | camaroneGreenDarkTheme |
| damaskLunar | damaskLunarLightTheme | damaskLunarDarkTheme |
| deepBlueSea | deepBlueSeaLightTheme | deepBlueSeaDarkTheme |
| deepPurple | deepPurpleLightTheme | deepPurpleDarkTheme |
| dellGenoaGreen | dellGenoaGreenLightTheme | dellGenoaGreenDarkTheme |
| ebonyClay | ebonyClayLightTheme | ebonyClayDarkTheme |
| eggplantPurple | eggplantPurpleLightTheme | eggplantPurpleDarkTheme |
| endeavourBlue | endeavourBlueLightTheme | endeavourBlueDarkTheme |
| espressoCrema | espressoCremaLightTheme | espressoCremaDarkTheme |
| flutterDash | flutterDashLightTheme | flutterDashDarkTheme |
| goldSunset | goldSunsetLightTheme | goldSunsetDarkTheme |
| greens | greensLightTheme | greensDarkTheme |
| greenForest | greenForestLightTheme | greenForestDarkTheme |
| greenJungle | greenJungleLightTheme | greenJungleDarkTheme |
| greenMoney | greenMoneyLightTheme | greenMoneyDarkTheme |
| greyLaw | greyLawLightTheme | greyLawDarkTheme |
| hippieBlue | hippieBlueLightTheme | hippieBlueDarkTheme |
| indigoNight | indigoNightLightTheme | indigoNightDarkTheme |
| indigoSanMarino | indigoSanMarinoLightTheme | indigoSanMarinoDarkTheme |
| lipstickPink | lipstickPinkLightTheme | lipstickPinkDarkTheme |
| mallardValencia | mallardValenciaLightTheme | mallardValenciaDarkTheme |
| mangoMojito | mangoMojitoLightTheme | mangoMojitoDarkTheme |
| material3 | material3LightTheme | material3DarkTheme |
| material3HighContrast | material3HighContrastLightTheme | material3HighContrastDarkTheme |
| material3Purple | material3PurpleLightTheme | material3PurpleDarkTheme |
| midnight | midnightLightTheme | midnightDarkTheme |
| mosqueCyan | mosqueCyanLightTheme | mosqueCyanDarkTheme |
| ohMandyRed | ohMandyRedLightTheme | ohMandyRedDarkTheme |
| outerSpace | outerSpaceLightTheme | outerSpaceDarkTheme |
| pinkSakura | pinkSakuraLightTheme | pinkSakuraDarkTheme |
| purpleBrown | purpleBrownLightTheme | purpleBrownDarkTheme |
| redBlue | redBlueLightTheme | redBlueDarkTheme |
| redTornado | redTornadoLightTheme | redTornadoDarkTheme |
| redWine | redWineLightTheme | redWineDarkTheme |
| rosewood | rosewoodLightTheme | rosewoodDarkTheme |
| rustDeepOrange | rustDeepOrangeLightTheme | rustDeepOrangeDarkTheme |
| sanJuanBlue | sanJuanBlueLightTheme | sanJuanBlueDarkTheme |
| sharkOrange | sharkOrangeLightTheme | sharkOrangeDarkTheme |
| thunderbirdRed | thunderbirdRedLightTheme | thunderbirdRedDarkTheme |
| verdunGreen | verdunGreenLightTheme | verdunGreenDarkTheme |
| verdunLime | verdunLimeLightTheme | verdunLimeDarkTheme |
| vesuviusBurned | vesuviusBurnedLightTheme | vesuviusBurnedDarkTheme |
| willowWasabi | willowWasabiLightTheme | willowWasabiDarkTheme |
| yukonGoldYellow | yukonGoldYellowLightTheme | yukonGoldYellowDarkTheme |
可以通过AppService实例对象的setColorTheme方法切换主题,其类型签名如下:
void setColorTheme(ColorThemesEnum themeEnum)
例如:
// 获取AppService实例
final AppService appService = GetIt.instance.get<AppService>();
// 切换主题为bigStoneTulip
appService.setColorTheme(ColorThemesEnum.bigStoneTulip);
ThemeModal
你可以使用ThemeModal模态对话框组件为用户提供更直观的主题选择,例如:
const ThemeModal(),
它会以主题图标的形式显示在页面上:

如果触摸或点击此图标,则会出现一个对话框供用户选择主题:

每个主题将以其primaryColor的圆形形状显示在模态对话框中,并且选中的主题会有勾选标记。
从版本3.0.0开始,你可以在ThemeModal组件中通过themes参数指定可用的主题。如果没有指定或者指定为空数组,则默认使用所有内置主题。
showThemeModal
showThemeModal是一个比ThemeModal更具灵活性的功能。例如:
// 某个组件的onTap参数
onTap: (_) {
showThemeModal(
context,
themes: [
ColorThemesEnum.amberBlue,
ColorThemesEnum.brownOrange,
ColorThemesEnum.dellGenoaGreen,
ColorThemesEnum.camaroneGreen,
],
);
},
2.2 暗色模式管理
在App Service库中,暗色/亮色模式是同一主题下的两个子状态,本质上定义了两组相应的主题数据。你可以直接通过AppService单例中的toggleDarkMode方法切换暗色模式:
// 获取AppService的单例实例
final AppService appService = GetIt.instance.get<AppService>();
// 切换暗色模式
appService.toggleDarkMode()
此外,在appService实例对象上还有setDarkMode和setLightMode方法用于设置暗色/亮色模式。
DarkModeSwitch是一个可以直接使用的开关,用于切换暗色模式。例如:

2.3 跟随系统模式
从V4.0.0版本开始,添加了一个新的功能:跟随系统的暗色模式。通过更改AppService中的followSystem属性的值,可以设置是否跟随系统。一旦手动更改了暗色模式,followSystem的值将被设置为false。followSystem是一个RxBool类型的变量,意味着它是响应式的。例如:
Obx(
() => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('app_service.follow_system'.tr + 'app_service.:'.tr),
Checkbox(
value: Get.find<AppService>().followSystem.value,
onChanged: (value) {
Get.find<AppService>().followSystem.value = value!;
Get.find<AppService>().saveFollowSystem();
},
),
],
),
),

系统模式跟随的行为因平台而异;在Windows平台上,它会强制跟随系统的暗色模式。
3. 本地化
3.1 消息
Messages是一个接受多个翻译的翻译容器。它的类型签名如下:
Messages Messages(List<Map<String, Map<String, String>>> translations)
你应该将其通过translations参数传递给顶级组件GetMaterialApp,并且必须包括AppServiceMessages().keys,这是App Service的一个翻译文件。例如:
GetMaterialApp(
translations: Messages([
AppServiceMessages().keys,
// 其他翻译
HomeMessages().keys,
]),
);
其中HomeMessages是一个假设的自定义翻译文件,看起来像这样:
import 'package:get/get.dart';
class HomeMessages extends Translations {
[@override](/user/override)
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 デモ',
},
// 更多语言翻译...
};
}
当然,根据项目的需要,你可以定义更多这样的翻译文件并加载到Messages的translations列表中。
在实现国际化时,通过AppService构造函数的supportedLanguages参数指定支持的语言。它接受一个由多个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: Locale(appService.currentLangStr),
home: const HomeView(),
);
要切换语言,可以使用AppService实例对象上的updateLocale方法,其类型签名如下:
void updateLocale(LanguageEnum newLanguage)
例如:
appService.updateLocale(LanguageEnum.zh);
3.2 本地语言切换
有两种可用的Widget用于显示语言选择菜单以切换本地语言:LangSelectMenu和Wen。
3.2.1 LangSelectMenu
LangSelectMenu是一个普通的矩形下拉按钮,例如:
const LangSelectMenu(),
它看起来像这样:

Wen也是一个弹出菜单的按钮,但它显示一个图标,通常在Header中使用:
const Wen()
它看起来像这样:

你可以自定义显示的图标及其大小,它可以是任何小部件。
LanguageSelectPage & CupertinoLanguageSelectPage
如果你想在一个设置页面中选择语言,可以考虑使用LanguageSelectPage或CupertinoLanguageSelectPage组件。这些组件代表一个语言选择页面,可以从设置项中打开。

3. Web 应用
在Web应用中,当前的sharedPreferencesWeb库通过localStorage实现键值对存储。AppService管理的相关状态的变化会直接反映在浏览器的localStorage中:

4. 示例应用
你可以在这里找到App Service的一个示例应用。
示例代码
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:app_service/app_service.dart';
import 'app/injections.dart';
import 'app/router.dart';
import 'modules/home/home_view.dart';
import 'modules/home/home_tr.dart';
void main() async {
Get.testMode = true;
WidgetsFlutterBinding.ensureInitialized();
Get.testMode = kDebugMode;
await initDependencies();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
final appService = Get.find<AppService>();
return GetMaterialApp(
debugShowCheckedModeBanner: Get.testMode,
title: switch (Get.locale?.toLanguageTag()) {
'zh' => 'AppService 演示 (zh)',
'zh-CN' => 'AppService 演示(陆)',
'zh-HK' => 'AppService 演示(港)',
'zh-MO' => 'AppService 演示(澳)',
'zh-TW' => 'AppService 演示(台)',
'en' => 'AppService Demo (en)',
'en-GB' => 'AppService Dem (GB)',
'en-US' => 'AppService Demo (US)',
'ru' => 'Демонстрация сервиса приложения',
'ru-RU' => 'Демонстрация сервиса приложения',
'ru-BY' => 'Дэма-версія паслугі',
'ru-UA' => 'Демо-версія служби',
'ru-KZ' => 'AppService Демо',
'fr' => 'AppService démonstration (fr)',
'ja' => 'AppServiceデモ (日)',
'ko' => 'App 서비스 데모',
'ar' => 'تطبيق AppService',
_ => 'AppService Demo',
},
theme: appService.currentTheme,
getPages: AppRoutes.routes,
translations: Messages([
AppServiceMessages().keys,
HomeMessages().keys,
]),
locale: Locale(appService.currentLangStr),
fallbackLocale: const Locale('en', 'US'),
home: const HomeView(),
);
}
}
更多关于Flutter应用服务插件app_service的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html


