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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:55:55