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',
}
};
}
2 ответа
Это проще сделать с помощью 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
класс инициализируется в зависимости от значения bool из хранилища. И это
themeData
file - это то, что вы передаете в свой, который выглядит так.
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
переменную в поле локали в
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())
}