使用 Provider 将 Map 的状态保存到 Flutter 应用
Posted
技术标签:
【中文标题】使用 Provider 将 Map 的状态保存到 Flutter 应用【英文标题】:Saving state of Map to Flutter app with Provider 【发布时间】:2021-02-25 09:53:36 【问题描述】:我有一个基于以下结构呈现的 ListView。该地图有大约 5 个“字符串”键值,每个都有 1 个 10-15 个项目模型的列表。 isDone 通过使用 toggleDone() 调用各个 ItemModel 来翻转。这会将布尔状态保存在应用程序中,但一旦应用程序关闭,它就会重置。我查看了共享首选项,但是 -
-
我不知道如何编码这个特定的地图,然后加载必要的值。
这是我应该在 Model 类上做的事情吗?
还是单独的 ItemModel 类?
有没有办法只对 bool 值进行编码然后加载这些值?
保存 Map 的 ChangeNotifier 类:
```
class Data extends ChangeNotifier
List<ItemModel> getData(name) => items[name];
Map<String, List<ItemModel>> items =
'String': [
ItemModel(
title: 'Some text',
text:
'Some other text',
isDone: false,
duration: Duration(
hours: 0,
minutes: 0,
seconds: 10,
),
),
]
;
ItemModel:
class ItemModel
final String title;
final String text;
bool isDone;
Duration duration;
ItemModel(
this.text, this.title, this.isDone = false, this.duration);
void toggleDone()
isDone = !isDone;
对于 List 中的每个 ItemModel,都会呈现一个如下所示的 Item。它需要 isDone 的 ItemModel 值来设置 isChecked 属性。
class Item extends StatelessWidget
final String title;
final String text;
final bool isChecked;
final Function checkboxCallback;
Item(
this.text,
this.title,
this.isChecked,
this.checkboxCallback);
@override
Widget build(BuildContext context)
return Padding(
child: ListTile(
leading: Checkbox(
value: isChecked,
onChanged: checkboxCallback,
),
title: Text(
title,
),
subtitle: isChecked
? Text('')
: Text(
text,
),
),
);
感谢您的帮助????
【问题讨论】:
【参考方案1】:正如您提到的,SharedPreferences 仅支持持久的原始值。假设您可以保证列表中 ItemModel
的每个实例的唯一键,您可以做的是围绕 SharedPreferences 编写自己的包装器:
import 'package:shared_preferences/shared_preferences.dart';
abstract class SharedPreferencesKeys
static const title = 'title';
static const text = 'text';
static const isDone = 'isDone';
static const duration = 'duration';
class SharedPreferencesImpl
SharedPreferences _preferences;
Future<SharedPreferences> get preferences async => _preferences ??= await SharedPreferences.getInstance();
Future<void> write(String key, ItemModel value) async
final sharedPrefs = await preferences;
await sharedPrefs.setString('$key_$SharedPreferencesKeys.title', value.title);
await sharedPrefs.setString('$key_$SharedPreferencesKeys.text', value.text);
await sharedPrefs.setBool('$key_$SharedPreferencesKeys.isDone', value.isDone);
await sharedPrefs.setInt('$key_$SharedPreferencesKeys.duration', value.duration.microseconds);
Future<ItemModel> read(String key) async
final sharedPrefs = await preferences;
final title = await sharedPrefs.getString('$key_$SharedPreferencesKeys.title');
final text = await sharedPrefs.getString('$key_$SharedPreferencesKeys.text');
final isDone = await sharedPrefs.getBool('$key_$SharedPreferencesKeys.isDone');
final microseconds = await sharedPrefs.getInt('$key_$SharedPreferencesKeys.duration');
return ItemModel(
title: title,
text: text,
isDone: isDone,
duration: Duration(microseconds: microseconds),
);
Future<void> delete(String key) async
final sharedPrefs = await preferences;
await sharedPrefs.remove('$key_$SharedPreferencesKeys.title');
await sharedPrefs.remove('$key_$SharedPreferencesKeys.text');
await sharedPrefs.remove('$key_$SharedPreferencesKeys.isDone');
await sharedPrefs.remove('$key_$SharedPreferencesKeys.duration');
【讨论】:
谢谢,我会试试这个!你知道为什么我得到错误“'await'应用于'int',这不是'Future'。”?您对实例化 SharedPreferencesImpl 类的最佳位置有意见吗? 我需要查看您的代码,显然您调用了一个错误的函数,该函数返回int
而不是 Future<bool>
但我不能不看就告诉您是哪一个。至于实例化的地方取决于你的架构。如果您刚开始使用 Flutter,请查看 BLoC 模式。另外,请查看 provider
和 riverpod
依赖注入包。以上是关于使用 Provider 将 Map 的状态保存到 Flutter 应用的主要内容,如果未能解决你的问题,请参考以下文章