Flutter:使用GetX实用程序函数时存储语言和主题偏好



使用GetX的实用程序函数时,是否有任何方法可以存储用户首选项(并在重新启动时检索(:

Get.changeTheme(ThemeData().dark)

以及

Get.updateLocale(Locale('en', 'US'));

到目前为止,我只能更改主题和语言,但我在GetX中没有找到将任何更改坚持到任何类型的存储的方法,以便在下次重新打开应用程序时加载。有什么东西我在俯瞰吗?有没有任何方法可以挂接到启动过程中,检查一些存储的值(例如在SharedPreferences中(,并将它们传递给我在GetMaterialApp中的localetheme属性?

这是我的代码:

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更容易做到这一点。

如果您只是从浅色主题更改为深色主题,那么每次更改主题时都需要存储一个简单的bool。

这里有一种使用基本设置类来实现这一点的方法。

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);
}

至于你们的语言设置,也是一样。只需向Getx类中添加一个Locale变量,存储几个字符串,在运行应用程序之前进行初始化,然后将该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())
}

最新更新