You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HydratedCubit实现Todo列表持久化失败问题求助

问题原因及解决方案

核心问题

HydratedCubit无法保存列表的根本原因是Todo模型未实现序列化/反序列化逻辑,且你的TodoListState代码存在拼写错误与逻辑混乱,导致JSON转换链断裂。

具体问题点

  1. Todo模型缺失序列化能力:JSON无法直接识别自定义Todo对象,必须为其添加json_serializable支持,否则即使给State加注解,列表里的Todo依然无法被转成可存储的JSON格式。
  2. TodoListState代码错误:你写的FoodListState是拼写错误(应为TodoListState),生成的.g.dart文件里误用了TodoModel而非Todo,导致序列化逻辑完全失效。
  3. 序列化链不完整:State的序列化依赖内部所有自定义对象的序列化能力,必须同时处理Todo和TodoListState的JSON转换。

分步修复方案

1. 为Todo模型添加序列化支持

修改todo.dart,添加json_serializable注解及对应的转换方法:

import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:uuid/uuid.dart';

part 'todo.g.dart';

Uuid uuid = const Uuid();

@JsonSerializable()
class Todo extends Equatable {
  final String id;
  final String desc;
  final double menge;

  Todo({
    String? id,
    required this.desc,
    required this.menge,
  }) : id = id ?? uuid.v4();

  // 从JSON转Todo对象
  factory Todo.fromJson(Map<String, dynamic> json) => _$TodoFromJson(json);
  // 从Todo对象转JSON
  Map<String, dynamic> toJson() => _$TodoToJson(this);

  @override
  List<Object?> get props => [id, desc, menge];
}

2. 修复TodoListState的代码错误

修改todo_list_state.dart,修正拼写错误并关联正确的序列化逻辑:

part of 'todo_list_cubit.dart';
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import '../models/todo.dart';

part 'todo_list_state.g.dart';

@JsonSerializable()
class TodoListState extends Equatable {
  final List<Todo> todos;

  const TodoListState({required this.todos});

  factory TodoListState.initial() {
    return const TodoListState(todos: []);
  }

  // 从JSON转State
  factory TodoListState.fromJson(Map<String, dynamic> json) => _$TodoListStateFromJson(json);
  // 从State转JSON
  Map<String, dynamic> toJson() => _$TodoListStateToJson(this);

  @override
  List<Object?> get props => [todos];
}

3. 修正HydratedCubit的序列化方法

修改todo_list_cubit.dart,直接使用State的fromJson/toJson方法:

import 'package:hydrated_bloc/hydrated_bloc.dart';
import '../models/todo.dart';

part 'todo_list_state.dart';
part 'todo_list_cubit.g.dart';

class TodoListCubit extends HydratedCubit<TodoListState> {
  TodoListCubit() : super(TodoListState.initial());

  // 示例:添加Todo的方法
  void addTodo({required String desc, required double menge}) {
    final newTodo = Todo(desc: desc, menge: menge);
    emit(TodoListState(todos: [...state.todos, newTodo]));
  }

  @override
  TodoListState? fromJson(Map<String, dynamic> json) {
    return TodoListState.fromJson(json);
  }

  @override
  Map<String, dynamic>? toJson(TodoListState state) {
    return state.toJson();
  }
}

4. 生成序列化代码并初始化存储

  • 运行命令生成.g.dart文件:
    flutter pub run build_runner build
    
  • 在main.dart中初始化HydratedStorage(必须确保在runApp之前执行):
    import 'package:flutter/material.dart';
    import 'package:hydrated_bloc/hydrated_bloc.dart';
    import 'package:path_provider/path_provider.dart';
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      // 初始化本地存储目录
      HydratedBloc.storage = await HydratedStorage.build(
        storageDirectory: await getApplicationDocumentsDirectory(),
      );
      runApp(const MyApp());
    }
    

验证逻辑

完成上述修改后,添加Todo后退出应用,重新启动时列表会自动恢复,因为:

  1. 每个Todo能转成JSON对象
  2. TodoListState能将List<Todo>转成JSON数组
  3. HydratedCubit会自动将State的JSON数据存储到本地,并在启动时读取恢复

内容的提问来源于stack exchange,提问作者Fabian M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 07:15:34