如何用Hive实现杀死进程后ListView的状态持久化(书签APP)
基于Hive实现书签APP的持久化解决方案
你的代码目前存在这些问题:
- 启动时没有从Hive加载已保存的数据,每次都用硬编码的默认列表
- 删除条目只更新了本地列表,没同步到Hive,重启后数据会自动恢复
- 仅在添加条目时才保存数据到Hive,其他操作没做持久化处理
下面是修改后的完整代码,完全满足你的需求:
late Box box; const bookmarkBox = 'bookmark_box'; Future<void> main() async { await Hive.initFlutter(); box = await Hive.openBox(bookmarkBox); runApp(const BookmarkApp()); } class BookmarkApp extends StatelessWidget { const BookmarkApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Bookmark App', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.white), useMaterial3: false, ), home: const BookmarkListPage(), ); } } class BookmarkListPage extends StatefulWidget { const BookmarkListPage({super.key}); final String title = 'Bookmark'; @override State<BookmarkListPage> createState() => _BookmarkListPageState(); } class _BookmarkListPageState extends State<BookmarkListPage> { late List<String> bookmarkList; late List<String> bookmarkUrl; @override void initState() { super.initState(); // 页面初始化时从Hive加载数据,无数据则用默认值 _loadBookmarks(); } void _loadBookmarks() { bookmarkList = box.get('BookmarkTitle', defaultValue: ['Google', 'Apple']).cast<String>(); bookmarkUrl = box.get('BookmarkUrl', defaultValue: [ 'https://www.google.com/', 'https://www.apple.com/jp/', ]).cast<String>(); } // 统一的书签保存方法,所有修改操作后都调用 void _saveBookmarks() { box.put('BookmarkTitle', bookmarkList); box.put('BookmarkUrl', bookmarkUrl); } _launchUrl(int index) async { var url = Uri.parse(bookmarkUrl[index]); if (await canLaunchUrl(url)) { await launchUrl(url); } else { throw "无法打开 $url"; } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, backgroundColor: Colors.white, title: Text( widget.title, style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.black), ), bottom: PreferredSize( child: Container( height: 1, color: Colors.black, ), preferredSize: const Size.fromHeight(1), ), ), body: ListView.builder( itemCount: bookmarkList.length, itemBuilder: (context, index) { return Dismissible( background: Container( color: Colors.red, child: const Icon( Icons.delete, color: Colors.white, ), ), onDismissed: (direction) { setState(() { bookmarkList.removeAt(index); bookmarkUrl.removeAt(index); // 删除后同步保存到Hive _saveBookmarks(); }); }, key: UniqueKey(), child: Card( child: ListTile( title: Text( bookmarkList[index], style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 20, ), ), subtitle: Text(bookmarkUrl[index]), onTap: () => _launchUrl(index), ), ), ); }, ), floatingActionButton: FloatingActionButton( shape: const CircleBorder(), backgroundColor: Colors.blue, onPressed: () async { final (newBookmarkTitle, newBookmarkUrl) = await showDialog( context: context, builder: (_) { return BookmarkDialog(); }); setState(() { bookmarkList.add(newBookmarkTitle); bookmarkUrl.add(newBookmarkUrl); _saveBookmarks(); }); }, child: const Icon( Icons.add, color: Colors.white, ), ), ); } }
关键修改说明:
- 初始化加载数据:在
initState中调用_loadBookmarks,优先从Hive读取已保存的书签,没有数据时才使用默认的Google和Apple条目 - 统一保存逻辑:新增
_saveBookmarks方法,添加、删除操作后都调用该方法,确保所有修改都持久化到Hive - 删除操作同步:删除条目时同时更新本地列表和Hive数据,避免重启后已删除的条目恢复
- 简化参数:移除了
BookmarkListPage中无用的text和url参数,精简代码
修改后,添加的条目会永久保存,删除默认条目后重启也不会恢复,完全符合你的需求。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

