#flutter #dart
#flutter #dart
Вопрос:
У меня есть ListView, который отображается на основе приведенной ниже структуры. Карта имеет около 5 «строковых» ключевых значений, каждое из которых содержит 1 список из 10-15 моделей элементов. isDone переключается путем вызова отдельных ItemModels с помощью toggleDone() . Это сохраняет состояние bool в приложении, но оно сбрасывается после закрытия приложения. Я изучил sharedprefences, но —
- Я не могу понять, как закодировать эту конкретную карту, а затем загрузить необходимые значения.
- Это даже то, что я должен делать в классе Model или отдельных классах ItemModel?
- Есть ли способ кодировать только значения bool, а затем загружать их?
Класс 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;
}
}
Для каждой ItemModel в списке отображается элемент, который выглядит следующим образом. Для установки свойства IsChecked требуется значение ItemModel isDone.
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}');
}
}
Комментарии:
1. Спасибо, я попробую это! Знаете ли вы, почему я получаю сообщение об ошибке «‘await’ применяется к ‘int’, которое не является ‘Future’.»? И есть ли у вас мнение о том, где лучше всего создать экземпляр класса SharedPreferencesImpl?
2. Мне нужно было бы увидеть ваш код, по-видимому, вы вызываете неправильную функцию, которая возвращает
int
вместоFuture<bool>
, но я не могу сказать вам, какой из них, не посмотрев. Что касается места для создания экземпляра, это зависит от вашей архитектуры. Если вы только начинаете с Flutter, взгляните на шаблон блоков. Кроме того, взгляните наprovider
иriverpod
пакеты для внедрения зависимостей.