Flutter:使用 GetX 实用程序函数时存储语言和主题偏好
Posted
技术标签:
【中文标题】Flutter:使用 GetX 实用程序函数时存储语言和主题偏好【英文标题】:Flutter: Storing language and theme preference when using GetX utility functions 【发布时间】:2021-03-11 16:57:33 【问题描述】:在使用 GetX 的实用程序功能时,有什么方法可以存储用户偏好(并在重新启动时检索它们):
Get.changeTheme(ThemeData().dark)
还有
Get.updateLocale(Locale('en', 'US'));
到目前为止,我只能更改主题和语言,但我还没有在 GetX 中找到一种方法来坚持对任何类型的存储进行任何更改,以便下次重新打开应用程序时加载。有什么我忽略的吗?有什么方法可以挂接到启动过程并检查一些存储的值(例如在SharedPreferences
中)并将它们传递给我在GetMaterialApp
中的locale
和theme
属性?
这是我的代码:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return GetMaterialApp(
translations: Messages(),
locale: Get.locale,
theme: Get.theme,
home: MyHomePage(),
);
class MyHomePage extends StatelessWidget
@override
Widget build(BuildContext context)
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () =>
Get.changeTheme(
Get.isDarkMode ? ThemeData.light() : ThemeData.dark())
,
child: Text('change_theme'.tr)),
TextButton(
onPressed: () =>
Get.updateLocale(Get.locale == Locale('en', 'US')
? Locale('de', 'DE')
: Locale('en', 'US'))
,
child: Text('change_language'.tr)),
],
));
class Messages extends Translations
@override
Map<String, Map<String, String>> get keys =>
'en_US':
'change_theme': 'Change Theme',
'change_language': 'Change Language',
,
'de_DE':
'change_theme': 'Farbschema wechseln',
'change_language': 'Sprache wechseln',
;
【问题讨论】:
【参考方案1】:使用GetStorage 更容易做到这一点。
如果您只是从浅色主题更改为深色主题,则每次更改主题时都存储一个简单的布尔值。
这是使用基本设置类执行此操作的一种方法。
class SettingsController extends GetxController
ThemeData themeData;
final box = GetStorage();
@override // called when you use Get.put before running app
void onInit()
super.onInit();
_restoreTheme();
void _restoreTheme()
bool isDark = box.read('isDark') ?? true; // null check for first time running this
if (isDark)
themeData = ThemeData.dark();
else
themeData = ThemeData.light();
void storeThemeSetting(bool isDark)
box.write('isDark', isDark);
SettingsController
类中的 themeData
变量根据存储中的布尔值进行初始化。 themeData
文件就是你传递给GetMaterialApp
的文件,看起来像这样。
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
final controller = Get.find<SettingsController>();
return GetMaterialApp(
theme: controller.themeData,
title: 'Material App',
home: StorageDemo(),
);
然后在运行您的应用之前将这两行都放入您的 Main 方法中。
await GetStorage.init();
Get.put(SettingsController());
这是一个演示页面,您可以在其中进行测试。
class StorageDemo extends StatelessWidget
Widget build(BuildContext context)
final controller = Get.find<SettingsController>();
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextButton(
onPressed: ()
Get.changeTheme(ThemeData.dark());
controller.storeThemeSetting(true);
,
child: Text('Dark Theme'),
),
TextButton(
onPressed: ()
Get.changeTheme(ThemeData.light());
controller.storeThemeSetting(false);
,
child: Text('Light Theme'),
),
],
),
),
);
如果您有一个更复杂的ThemeData
文件,那么同样的概念也适用,但您必须单独存储每种颜色,我发现通过存储颜色的int
值最容易做到这一点。
int colorValue = Colors.red.value; // store this int
那么在从存储中恢复的时候就可以使用这个功能了
Color mapIntToColor(int value)
return Color(value);
至于您的语言设置,同样的事情。只需将Locale
变量添加到您的Getx 类,存储几个字符串,在运行应用程序之前进行初始化,然后将该Locale
变量传递到GetMaterialApp
的区域设置字段中。
【讨论】:
【参考方案2】:应该可以使用 SharedPreferences。分配可以保存和读取的键值对(例如主题、深色)或(主题、浅色),然后在它们上运行逻辑以在打开应用程序时调用 ThemeData。
保存:
_saveTheme() async
final prefs = await SharedPreferences.getInstance();
final key = 'theme';
final value = _theme;
prefs.setString(key, value);
在初始化应用程序和设置主题时阅读 - 类似这样(我没有测试):
_readTheme(context) async
final prefs = await SharedPreferences.getInstance();
final key = 'theme';
final _theme = prefs.getString(key) ?? "light"; //set theme to light if the key is not found in SharedPreferences
Get.changeTheme(
_theme == 'light' ? ThemeData.light() : ThemeData.dark())
【讨论】:
好的,您能否提供一些代码示例,使用我在上面发布的代码来说明您将如何“在打开应用程序时调用 ThemeData”? 我编辑了我的答案以展示我会在你的情况下做什么 - 你需要进行一些试验并在需要的地方进行微调以上是关于Flutter:使用 GetX 实用程序函数时存储语言和主题偏好的主要内容,如果未能解决你的问题,请参考以下文章
发布到 Firebase Analytics 时,启用 getx 的 Flutter 应用程序是不是支持 FirebaseAnalyticsObserver 对象?
对 Flutter 应用程序的 getX dart 包中的 RxList 进行排序