如何解决Flutter:使用 GetX 实用程序函数时存储语言和主题偏好
在使用 GetX 的实用功能时,有什么方法可以存储用户首选项(并在重新启动时检索它们):
Get.changeTheme(ThemeData().dark)
以及
Get.updateLocale(Locale('en','US'));
到目前为止,我只能更改主题和语言,但我还没有在 GetX 中找到一种方法来坚持我对任何类型的存储所做的任何更改,以便下次重新打开应用程序时加载。有什么我忽略的吗?有没有办法挂钩到启动过程并检查一些存储的值(例如在 SharedPreferences
中)并将它们传递给我在 locale
中的 theme
和 GetMaterialApp
属性?
这是我的代码:
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',}
};
}
解决方法
使用 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);
}
}
themeData
类中的 SettingsController
变量根据存储中的 bool 值进行初始化。而那个 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
中的区域设置字段。
使用 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())
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。