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