Flutter 存储共享首选项中的自定义类列表

Posted

技术标签:

【中文标题】Flutter 存储共享首选项中的自定义类列表【英文标题】:Flutter store List of custom Classes in Shared Preferences 【发布时间】:2021-12-30 22:19:16 【问题描述】:

我有自定义对象列表,这些对象也具有非原始数据类型的字段。我想将这些对象的list 存储在SharedPreferences 中。这是我的List,也是简单的Data

@JsonSerializable()
class MedicamentsBase 
  final List<Medicament> data;

  const MedicamentsBase(
    required this.data,
  );

  factory MedicamentsBase.fromJson(Map<String, dynamic> json) =>
      _$MedicamentsBaseFromJson(json);
  Map<String, dynamic> toJson() => _$MedicamentsBaseToJson(this);




@JsonSerializable()
class Medicament 
  @JsonKey(name: '_id')
  String id;
  String name;
  int dosageAmount;
  String dosageType;
  DateTime startDate;
  DateTime endDate;
  List<DateTime> timesOfDay;
  String intakeContext;
  bool notify;
  int notificationId;

  Medicament(
    required this.name,
    required this.dosageAmount,
    required this.dosageType,
    required this.startDate,
    required this.endDate,
    required this.timesOfDay,
    required this.intakeContext,
    required this.notify,
    required this.notificationId,
    required this.id,
  );

  factory Medicament.fromJson(Map<String, dynamic> json) =>
      _$MedicamentFromJson(json);
  Map<String, dynamic> toJson() => _$MedicamentToJson(this);


我已经对它们进行了序列化。但如果我尝试像这样存储MedicamentsBase

   static Future<void> setMedicaments(List<Medicament> medicaments) async 
    final SharedPreferences _sharedPreferences =
        await SharedPreferences.getInstance();

    await _sharedPreferences.setStringList(
      'key',
      medicaments.map((medicament) => json.encode(medicament)).toList(),
    );
  

如果尝试像这样取回列表,事情将无法按预期工作:

   static Future<List<Medicament>> getMedicaments() async 
    final SharedPreferences _sharedPreferences =
        await SharedPreferences.getInstance();

    return MedicamentsBase.fromJson(
      _sharedPreferences.getStringList('key') as Map<String, dynamic>,
    ).data;
  

我认为这是因为Medicament 中也有StringsDateTimes。在Shared Preferences中存储和获取此类数据的正确方法是什么?

【问题讨论】:

是否有“必须”使用 SharedPreferences?因为您可以使用 hive 轻松处理这种情况。 @Xoltawn 不是绝对必须的,但绝对是首选。我读过关于 Hive 的文章,但我认为实施它会更加努力,而且在这种情况下时间/金钱很少:D 在我看来这是值得的。如果你潜入它,你会发现它并不像第一眼看上去那么可怕。但我没有在 SharedPreferences 中完成这个场景,所以我对此没有意见。 我会看看它,因为它看起来很有希望。但是现在我会坚持SF。无论如何谢谢:) 如何将列表编码为单个字符串,而不是将列表项编码为字符串列表? 【参考方案1】:

如果您打算保存更复杂的数据类型,共享首选项可能不是最佳选择,我认为您的选择是:

了解如何使用 hive 包 尝试保存原始类型,以后可以使用共享首选项来重构复杂的数据类型 在您的复杂数据类型中创建一个 ToJson / FromJson 函数,并使用作为 Flutter 的一部分提供的 file.dart 函数将此数据保存为 json 文件,看看那些应该有用的函数:

写入文件:

    Directory applicationDocumentDirectory =
        await getApplicationDocumentsDirectory();
    File file = Directory applicationDocumentDirectory =
        await getApplicationDocumentsDirectory();

    Map<String, dynamic> fileJson = yourDataType.toJson();
    String dataAsJsonString = jsonEncode(fileJson);
    songDataFile.writeAsStringSync(dataAsJsonString);


    String fileData = file.readAsStringSync();

    return jsonDecode(fileData);

读取文件:

    Directory applicationDocumentDirectory =
        await getApplicationDocumentsDirectory();
    File file = Directory applicationDocumentDirectory =
        await getApplicationDocumentsDirectory();

    String fileData = file.readAsStringSync();

    return jsonDecode(fileData);

希望这些想法有所帮助:)

【讨论】:

以上是关于Flutter 存储共享首选项中的自定义类列表的主要内容,如果未能解决你的问题,请参考以下文章

将检索到的json转换为flutter中的自定义对象列表

Flutter:使用共享首选项插件存储保存的收藏列表

如何使用 dart/flutter 中的共享首选项保存和获取列表列表

我的共享首选项存储列表视图的数据并检索它不起作用

Flutter - 如何将 List<Uint8List> 放入共享首选项中?

如何在flutter中将具有文档ID的自定义对象设置为firestore中的集合?