Flutter实现点击按钮在首页添加Explore页面选中的Card组件求助
Flutter 实现收藏/书签功能
问题概述
需要实现:在Explore页面点击Card右侧的添加按钮,将该Card内容同步到Home页面展示。
解决方案
通过父组件维护状态+回调传递数据的方式实现,无需复杂状态管理库,适合入门场景:
1. 定义统一数据模型
创建Item类封装Card的所有数据,方便跨页面传递:
class Item { final String title; final String subtitle; final String avatarUrl; Item({required this.title, required this.subtitle, required this.avatarUrl}); }
2. 改造Home页面,负责收藏数据管理
将原pushAdd替换为展示收藏列表的FavoritePage,同时在Home中维护收藏列表,并提供添加收藏的方法:
import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'explore.dart'; import 'fav.dart'; import 'login.dart'; class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @override _HomeState createState() => _HomeState(); } class _HomeState extends State<Home> { late String uid; int _selectedIndex = 0; final List<Item> _favoriteItems = []; // 添加收藏,自动去重 void _addFavorite(Item item) { setState(() { if (!_favoriteItems.any((e) => e.title == item.title)) { _favoriteItems.add(item); } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Home'), actions: [ IconButton( icon: const Icon(Icons.logout), onPressed: () async { await FirebaseAuth.instance.signOut(); Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => const LoginScreen()), (route) => false, ); }, ) ], ), bottomNavigationBar: BottomNavigationBar( items: const <BottomNavigationBarItem>[ BottomNavigationBarItem(icon: Icon(Icons.home_outlined), label: 'Home'), BottomNavigationBarItem(icon: Icon(Icons.book_outlined), label: 'Explore'), BottomNavigationBarItem(icon: Icon(Icons.person_outlined), label: 'Profile'), ], currentIndex: _selectedIndex, onTap: _onItemTapped, ), body: IndexedStack( index: _selectedIndex, children: [ FavoritePage(favoriteItems: _favoriteItems), ExploreScreen(onAddFavorite: _addFavorite), const RandWords(), ], ), ); } @override void initState() { super.initState(); uid = FirebaseAuth.instance.currentUser!.uid; } void _onItemTapped(int index) => setState(() => _selectedIndex = index); } // 展示收藏内容的页面 class FavoritePage extends StatelessWidget { final List<Item> favoriteItems; const FavoritePage({Key? key, required this.favoriteItems}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: favoriteItems.isEmpty ? const Center(child: Text('暂无收藏内容')) : ListView.builder( itemCount: favoriteItems.length, itemBuilder: (context, index) { final item = favoriteItems[index]; return Card( child: ListTile( title: Text(item.title), subtitle: Text(item.subtitle), leading: CircleAvatar(backgroundImage: NetworkImage(item.avatarUrl)), ), ); }, ), ); } }
3. 修改Explore页面,绑定收藏逻辑
让ExploreScreen接收添加收藏的回调,点击按钮时传递对应Item数据:
import 'package:flutter/material.dart'; import 'home.dart'; class ExploreScreen extends StatelessWidget { final Function(Item) onAddFavorite; const ExploreScreen({Key? key, required this.onAddFavorite}) : super(key: key); @override Widget build(BuildContext context) => ListViewHome(onAddFavorite: onAddFavorite); } class ListViewHome extends StatelessWidget { final Function(Item) onAddFavorite; final List<Item> items = [ Item( title: "List 1", subtitle: "Here is list 1 subtitle", avatarUrl: "https://images.unsplash.com/photo-1547721064-da6cfb341d50", ), Item( title: "List 2", subtitle: "Here is list 2 subtitle", avatarUrl: "https://images.unsplash.com/photo-1547721064-da6cfb341d50", ), Item( title: "List 3", subtitle: "Here is list 3 subtitle", avatarUrl: "https://images.unsplash.com/photo-1547721064-da6cfb341d50", ), Item( title: "List 4", subtitle: "Here is list 4 subtitle", avatarUrl: "https://images.unsplash.com/photo-1547721064-da6cfb341d50", ), ]; ListViewHome({Key? key, required this.onAddFavorite}) : super(key: key); @override Widget build(BuildContext context) { return ListView.builder( itemCount: items.length, itemBuilder: (context, index) { final item = items[index]; return Card( child: ListTile( title: Text(item.title), subtitle: Text(item.subtitle), leading: CircleAvatar(backgroundImage: NetworkImage(item.avatarUrl)), trailing: IconButton( onPressed: () { onAddFavorite(item); // 添加收藏提示 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('已添加「${item.title}」到收藏')), ); }, icon: const Icon(Icons.add), ), ), ); }, ); } }
效果演示

内容的提问来源于stack exchange,提问作者Ankit Kumar
相关产品推荐
相关产品推荐

