![](/img/trans.png)
[英]How to store a List<Object> to Shared Preferences in Flutter?
[英]How to add a List with widgets to Shared Preferences in Flutter?
如何在不使用在线的情况下将小部件列表数据离线保存到用户手机中。我可以使用共享首选项来保存小部件列表数据还是有任何其他方法。实际上我在做的是我想保存列表并再次显示当用户返回我的应用程序但现在应用程序忘记了带有空列表的数据时。
class AlarmData extends ChangeNotifier {
List<Alarm> _alarms = [
Alarm(time:'04:05:06'),
Alarm(time:'04:05:06'),
Alarm(time:'04:05:06'),
];
UnmodifiableListView<Alarm> get alarms{
return UnmodifiableListView(_alarms);
}
void addAlarm(String newTaskTitle) {
final task = Alarm(time: newTaskTitle);
_alarms.add(task);
notifyListeners();
}
void updateAlarm(Alarm task) {
task.toggleDone();
notifyListeners();
}
void deleteAlarm(Alarm task) {
_alarms.remove(task);
notifyListeners();
}
int get alarmCount {
return alarms.length;
}
}
在此先感谢我是 flutter 开发的新手。
我能想到的一种方法是将它们编码为 Json 并将它们作为字符串保存在 sharedPreferences 中或作为应用程序目录中的文件(使用 path_provider)
class Alarm{
final String time;
Alarm({this.time});
@override
toString(){
return 'time: $time';
}
Map<String, dynamic> toJson() => {
'time': this.time
};
factory Alarm.fromJson(Map<String, dynamic> alarm) => Alarm(
time: alarm["time"],
);
}
您的 class 警报需要 fromJson 和 toJson 才能正确进行编码/解码。 我不知道它是否有其他参数,但您可以在构造函数和 from/to Json 中轻松添加它们
//You could put this method inside AlarmData if you want to save it everytime you update your changeNotifier
Future<void> saveAlarms(List<Alarm> alarms) async{
//Option 1 using SharedPreferences
final SharedPreferences preferences = await SharedPreferences.getInstance();
final String jsonEncoded = json.encode(alarms);
await preferences.setString('MyAlarms', jsonEncoded);
//Option 2 saving a json file in the documentsDirectory of the App
final Directory appDocDir = await getApplicationDocumentsDirectory();
final file = File('${appDocDir.path}/MyAlarms.json');
await file.writeAsString(jsonEncoded);
}
Future<List<Alarm>> get retrieveAlarms async{
//Option 1 using SharedPreferences
final SharedPreferences preferences = await SharedPreferences.getInstance();
final String myAlarms = await preferences.getString('MyAlarms');
if(myAlarms?.isEmpty ?? true) return <Alarm>[]; //check for null or empty values
final alarms = json.decode(myAlarms) as List;
return List<Alarm>.from(alarms.map((x) => Alarm.fromJson(x)));
//Option 2 saving a json file in the documentsDirectory of the App
final Directory appDocDir = await getApplicationDocumentsDirectory();
final readFile = File('${appDocDir.path}/MyAlarms.json');
if(!(await readFile.exists())) return <Alarm>[]; //check if the file exists
String jsonAlarms = await readFile.readAsString();
final jResult = jsonDecode(jsonAlarms) as List;
return List<Alarm>.from(jResult.map((x) => Alarm.fromJson(x)));
}
现在您的 AlarmData 需要一个构造函数,您可以在其中为它提供保存的警报列表
class AlarmData extends ChangeNotifier{
List<Alarm> _alarms;
AlarmData(this._alarms);
...
}
如果您在应用程序开始时或在 AlarmData 之前需要它,您可以在 main 中完成未来的 retrieveAlarms
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final myAlarms = await retrieveAlarms;
runApp(const HomePage(myAlarms)); //if you want to use it as soon as possible
}
如果您不介意使用另一个 package 我建议使用Hive ,它允许您存储对象和原始值(就像 sharedPreferences 一样)
@HiveType(typeId: 0)
class Alarms extends HiveObject {
@HiveField(0)
String time;
}
Future<void> _initHive() async {
final appDocumentDir = await getApplicationDocumentsDirectory();
Hive.init(appDocumentDir.path);
Hive.registerAdapter<Alarms>(AlarmsAdapter()); //check the documentation of hive about how to generate this file
await Hive.openBox<Alarms>('Alarm'); //a box where all your alarms are
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await _initHive(); //if you want to use it as soon as possible
runApp(const HomePage());
}
我看到您的 class 扩展了 ChangeNotifier,使用 Hive 它有一个开箱即用的可收听选项,因此无论何时您更改(添加或删除警报)它都会更新
ValueListenableProvider<Box<Alarm>>.value( //in case you're using provider package
value: Hive.box<Alarm>('Alarm').listenable(),
),
或者
ValueListenableBuilder(
valueListenable: Hive.box<Alarm>('Alarm').listenable(),
builder: (context) => ...
),
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.