如何使用Flutter Hive实现语录APP的收藏按钮及收藏页码展示功能?
用Hive实现Flutter语录APP的收藏功能
嘿,作为Flutter初学者能想到用Hive来简化本地存储真的很棒!它轻量、易用,完全适合你的收藏需求。我来一步步带你实现这个功能:
第一步:添加Hive依赖
首先在你的pubspec.yaml里添加必要的依赖:
dependencies: flutter: sdk: flutter hive: ^2.2.3 hive_flutter: ^1.1.0 dev_dependencies: flutter_test: sdk: flutter build_runner: ^2.1.11 hive_generator: ^1.1.5
然后运行flutter pub get安装依赖。
第二步:创建Hive数据模型
我们定义一个收藏项的模型,用来存储你要标记的页码(如果需要也可以扩展加上语录内容)。创建一个favorite_quote.dart文件:
import 'package:hive/hive.dart'; part 'favorite_quote.g.dart'; @HiveType(typeId: 0) class FavoriteQuote extends HiveObject { @HiveField(0) final int pageNumber; FavoriteQuote({required this.pageNumber}); }
然后运行命令生成适配器:
flutter packages pub run build_runner build
第三步:初始化Hive
在你的main.dart里初始化Hive,注册适配器并打开存储收藏的盒子:
import 'package:flutter/material.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'favorite_quote.dart'; import 'p1.dart'; // 导入你的页面 void main() async { await Hive.initFlutter(); Hive.registerAdapter(FavoriteQuoteAdapter()); await Hive.openBox<FavoriteQuote>('favorites'); runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: '语录APP', home: p1(), ); } }
第四步:修改你的p1页面,整合Hive收藏逻辑
现在更新你的p1页面,让收藏状态从Hive读取,点击按钮时同步更新Hive:
import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'favorite_quote.dart'; // 假设你用的是第三方favorite_button包,若没有可自行实现图标按钮 import 'package:favorite_button/favorite_button.dart'; class p1 extends StatefulWidget { @override _p1State createState() => _p1State(); } class _p1State extends State<p1> { late bool _isFavorite; late Box<FavoriteQuote> _favoriteBox; final int _pageNumber = 1; // 当前页面的页码 @override void initState() { super.initState(); _favoriteBox = Hive.box<FavoriteQuote>('favorites'); // 检查当前页码是否已在收藏列表中 _isFavorite = _favoriteBox.values.any((quote) => quote.pageNumber == _pageNumber); } void _toggleFavorite() { setState(() { _isFavorite = !_isFavorite; }); if (_isFavorite) { // 添加到收藏 _favoriteBox.add(FavoriteQuote(pageNumber: _pageNumber)); } else { // 从收藏移除 final itemToDelete = _favoriteBox.values.firstWhere( (quote) => quote.pageNumber == _pageNumber, orElse: () => FavoriteQuote(pageNumber: -1), ); if (itemToDelete.pageNumber != -1) { itemToDelete.delete(); } } } @override Widget build(BuildContext context) { return Scaffold( // 移除嵌套的MaterialApp,路由主题统一由main.dart管理 appBar: AppBar( title: Text('语录页面 $_pageNumber'), // 添加收藏列表入口按钮 actions: [ IconButton( icon: Icon(Icons.bookmark), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => FavoriteListPage()), ); }, ), ], ), body: Stack( children: <Widget>[ Image( image: AssetImage("Image/Chowsun1.jpg"), fit: BoxFit.cover, width: double.infinity, height: double.infinity, ), Align( alignment: Alignment.center, child: Text( ' Hello world ', style: TextStyle( fontSize: 35.0, color: Colors.white, fontFamily: "Explora", fontWeight: FontWeight.w900, ), ), ), Align( alignment: Alignment.bottomLeft, child: Text( ' $_pageNumber ', style: TextStyle( fontSize: 25.0, fontFamily: "MonteCarlo", color: Colors.white, fontWeight: FontWeight.w900, ), ), ), Align( alignment: Alignment.bottomCenter, child: FavoriteButton( isFavorite: _isFavorite, iconSize: 40, iconDisabledColor: Colors.red, iconColor: Colors.white, valueChanged: (isFav) => _toggleFavorite(), ), ) ], ), ); } }
第五步:创建收藏列表页面
现在做一个FavoriteListPage,用来展示所有收藏的页码,点击可以跳转对应页面:
import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'favorite_quote.dart'; import 'p1.dart'; // 可根据你的页面结构扩展导入p2、p3等 class FavoriteListPage extends StatelessWidget { @override Widget build(BuildContext context) { final Box<FavoriteQuote> _favoriteBox = Hive.box<FavoriteQuote>('favorites'); return Scaffold( appBar: AppBar( title: Text('我的收藏'), ), body: ValueListenableBuilder( valueListenable: _favoriteBox.listenable(), builder: (context, Box<FavoriteQuote> box, _) { if (box.values.isEmpty) { return Center(child: Text('还没有收藏任何语录')); } return ListView.builder( itemCount: box.values.length, itemBuilder: (context, index) { final favorite = box.getAt(index)!; return ListTile( title: Text('语录页面 ${favorite.pageNumber}'), onTap: () { // 根据页码跳转对应页面,这里可扩展为多页面判断逻辑 Navigator.push( context, MaterialPageRoute( builder: (context) => p1(), // 替换为对应页码的页面 ), ); }, trailing: IconButton( icon: Icon(Icons.delete), onPressed: () { favorite.delete(); }, ), ); }, ); }, ), ); } }
这里用ValueListenableBuilder可以让页面在Hive数据变化时自动刷新,无需手动调用setState。
一些小提示
- 如果你有多个语录页面,可以把页码作为参数传递给页面组件,避免重复写代码
- 可以给
FavoriteQuote模型添加quoteContent字段,让收藏列表直接预览语录内容 - Hive的盒子会自动管理生命周期,APP运行期间无需手动关闭
这样你就完成了收藏功能的实现:页面底部的收藏按钮可以标记/取消收藏,AppBar的书签按钮可以查看所有收藏的页面,数据会持久化存储在本地,重启APP也不会丢失!
内容的提问来源于stack exchange,提问作者Arefin




