Flutter集成Hive实现本地待办存储技术求助
Flutter集成Hive实现待办存储代码修正指南
我是Flutter纯新手,想集成Hive做待办事项本地存储,现在写了部分代码但卡壳了,求指出代码里要增删改的地方。
一、主函数代码修正
原主函数存在代码未闭合和Hive初始化流程不完整的问题,修正后:
import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:hive/hive.dart'; import 'package:hive_flutter/hive_flutter.dart'; void main() async { await Hive.initFlutter(); Hive.registerAdapter(TodoAdapter()); // 提前打开待办存储盒(也可在页面initState中打开) await Hive.openBox<Todo>('todoBox'); runApp( MaterialApp( debugShowCheckedModeBanner: false, home: Builder( builder: (context) { return GestureDetector( onTap: () { FocusScope.of(context).unfocus(); }, child: const TodoApp(), ); // 补全GestureDetector闭合 }, ), ), ); // 补全MaterialApp闭合 }
二、Todo类与Adapter核心修正
1. Todo类调整
原Todo的_tasknumber会在APP重启后重置,建议移除自增key,改用Hive内置存储能力,直接继承HiveObject简化操作:
class Todo extends HiveObject { String text; bool checked; int priority; Todo({ required this.text, required this.checked, required this.priority, }); }
2. Adapter必须实现序列化/反序列化
原Adapter的read和write方法为空,这是Hive存储的核心逻辑,必须补全:
class TodoAdapter extends TypeAdapter<Todo> { @override final int typeId = 0; // 每个实体的typeId唯一,不能重复 @override Todo read(BinaryReader reader) { return Todo( text: reader.readString(), checked: reader.readBool(), priority: reader.readInt(), ); } @override void write(BinaryWriter writer, Todo obj) { writer.writeString(obj.text); writer.writeBool(obj.checked); writer.writeInt(obj.priority); } }
三、TodoApp状态类修正
原状态类存在await不能直接写在类作用域、数据未从Hive加载、资源未正确释放等问题,修正后:
class TodoApp extends StatefulWidget { const TodoApp({super.key}); @override State<TodoApp> createState() => _TodoAppState(); } class _TodoAppState extends State<TodoApp> { final _textyController = TextEditingController(); late Box<Todo> _todoBox; // 声明Hive存储盒 List<Todo> data = []; int? _radioValue = 1; bool isEditing = false; int editingIndex = -1; bool isContainerVisible = false; bool settingsVisibility = false; final FocusNode _textFocus = FocusNode(); @override void initState() { super.initState(); _initHive(); _textFocus.addListener(() { setState(() { isContainerVisible = _textFocus.hasFocus; }); }); } // 异步初始化Hive并加载数据 Future<void> _initHive() async { _todoBox = await Hive.openBox<Todo>('todoBox'); setState(() { data = _todoBox.values.toList(); }); } @override void dispose() { _textyController.dispose(); _textFocus.dispose(); super.dispose(); } // 新增:删除待办的方法(同步到Hive) void deleteTasks(int index) { _todoBox.deleteAt(index); setState(() { data.removeAt(index); if (editingIndex == index) { isEditing = false; _textyController.clear(); _radioValue = 1; } }); } }
四、编辑/删除功能修正
原代码未同步Hive存储,且deleteTasks未定义,修正后:
SlidableAction( backgroundColor: Colors.green, icon: Icons.edit, onPressed: (context) { setState(() { isEditing = true; editingIndex = index; _textyController.text = data[index].text; _radioValue = data[index].priority; _textFocus.requestFocus(); }); }, ), SlidableAction( backgroundColor: Colors.red[400] ?? Colors.red, icon: Icons.delete_forever, onPressed: (context) { deleteTasks(index); Slidable.of(context)?.close(); }, ),
五、添加/编辑待办功能修正
原代码未同步Hive存储,且TextField编辑时新建controller易导致内存泄漏,修正后:
1. Radio按钮逻辑修正
Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Radio( value: 1, groupValue: isEditing ? data[editingIndex].priority : _radioValue, onChanged: (changedRadio) { setState(() { if (isEditing) { data[editingIndex].priority = changedRadio ?? 1; } else { _radioValue = changedRadio; } _textFocus.requestFocus(); }); }, fillColor: MaterialStateProperty.all(Colors.red), ), // 可补充其他优先级的Radio(如value:2、3) ], ),
2. TextField提交逻辑修正
child: TextField( focusNode: _textFocus, controller: _textyController, // 始终复用同一个controller onSubmitted: (value) { setState(() { if (isEditing) { final updatedTodo = Todo( text: value, checked: data[editingIndex].checked, priority: data[editingIndex].priority, ); _todoBox.putAt(editingIndex, updatedTodo); data[editingIndex] = updatedTodo; isEditing = false; } else { final newTodo = Todo( text: value, checked: false, priority: _radioValue ?? 1, ); _todoBox.add(newTodo); data.insert(0, newTodo); } _textyController.clear(); _textFocus.requestFocus(); _textyController.selection = TextSelection.fromPosition( TextPosition(offset: _textyController.text.length), ); }); }, ),
内容的提问来源于stack exchange,提问作者Hans Ramzan
相关产品推荐
相关产品推荐

