Один из способов, который я мог придумать, - это кодировать их как Json и сохранять их как String либо в 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"],
);
}
вашему классу Alarm нужны fromJson и toJson, чтобы правильно кодировать / декодировать. Я не знаю, есть ли у него другие параметры, но вы можете легко добавить их в конструктор и из / в 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);
...
}
Вы либо выполняете future retrieveAlarms в основном, если вам это нужно в начале работы приложения, либо непосредственно перед AlarmData.
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final myAlarms = await retrieveAlarms;
runApp(const HomePage(myAlarms)); //if you want to use it as soon as possible
}
Если вы не против использования другого пакета, я бы рекомендовал использовать 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());
}
Я вижу, что ваш класс расширяет ChangeNotifier, с Hive у него есть опция Listenable из коробки, поэтому каждый раз, когда вы меняете (добавляете или удаляете будильник), он будет обновляться
ValueListenableProvider<Box<Alarm>>.value( //in case you're using provider package
value: Hive.box<Alarm>('Alarm').listenable(),
),
OR
ValueListenableBuilder(
valueListenable: Hive.box<Alarm>('Alarm').listenable(),
builder: (context) => ...
),
person
EdwynZN
schedule
04.06.2020