如何实现点击ListTile跳转并查询Firestore同一文档ID显示更多字段
Flutter + Firestore 列表点击跳转详情页实现方案
1. 定义数据模型(推荐)
把Firestore文档转成实体类,避免反复写data()['字段名'],方便字段访问和页面传参:
class Item { final String id; final String title; final String subtitle; final String desc; // 详情页展示的额外字段 final int count; // 另一个额外字段 Item({ required this.id, required this.title, required this.subtitle, required this.desc, required this.count, }); // 从Firestore文档转成Item实例 factory Item.fromFirestore(DocumentSnapshot doc) { final data = doc.data() as Map<String, dynamic>; return Item( id: doc.id, title: data['title'] ?? '', subtitle: data['subtitle'] ?? '', desc: data['desc'] ?? '', count: data['count'] ?? 0, ); } }
2. 列表页面实现
用StreamBuilder监听Firestore集合的实时数据,通过ListView.builder构建列表,点击ListTile时跳转到详情页:
class ListPage extends StatelessWidget { @override Widget build(BuildContext context) { // 替换为你的Firestore集合路径 final collectionRef = FirebaseFirestore.instance.collection('your_collection'); return Scaffold( appBar: AppBar(title: const Text('列表页')), body: StreamBuilder<QuerySnapshot>( stream: collectionRef.snapshots(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } final items = snapshot.data!.docs.map((doc) => Item.fromFirestore(doc)).toList(); return ListView.builder( itemCount: items.length, itemBuilder: (context, index) { final item = items[index]; return ListTile( title: Text(item.title), subtitle: Text(item.subtitle), // 展示第三个字段,这里用leading示例 leading: Text('${item.count}'), onTap: () { // 跳转详情页,直接传递Item对象 Navigator.push( context, MaterialPageRoute( builder: (context) => DetailPage(item: item), ), ); }, ); }, ); }, ), ); } }
3. 详情页面实现
接收列表页传递的Item对象,直接展示所有需要的字段:
class DetailPage extends StatelessWidget { final Item item; const DetailPage({super.key, required this.item}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(item.title)), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('副标题: ${item.subtitle}'), const SizedBox(height: 8), Text('数量: ${item.count}'), const SizedBox(height: 8), Text('详情描述: ${item.desc}'), // 继续添加需要展示的其他字段 ], ), ), ); } }
可选:按文档ID查询详情(实时更新场景)
如果需要详情页实时同步Firestore数据,可以只传递文档ID,在详情页重新查询:
// 列表页跳转时传ID onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => DetailPage(docId: item.id), ), ); } // 详情页实现 class DetailPage extends StatelessWidget { final String docId; const DetailPage({super.key, required this.docId}); @override Widget build(BuildContext context) { final docRef = FirebaseFirestore.instance.collection('your_collection').doc(docId); return Scaffold( appBar: const AppBar(title: Text('详情页')), body: StreamBuilder<DocumentSnapshot>( stream: docRef.snapshots(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError || !snapshot.hasData) { return const Center(child: Text('加载失败')); } final item = Item.fromFirestore(snapshot.data!); return Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('标题: ${item.title}'), const SizedBox(height: 8), Text('副标题: ${item.subtitle}'), const SizedBox(height: 8), Text('数量: ${item.count}'), const SizedBox(height: 8), Text('详情描述: ${item.desc}'), ], ), ); }, ), ); } }
注意事项
- 确保项目已配置Firebase,并添加
cloud_firestore依赖到pubspec.yaml - Firestore文档的字段名要和代码中使用的完全一致
- 不需要实时更新的话,可将
StreamBuilder替换为FutureBuilder,调用get()方法获取数据
内容的提问来源于stack exchange,提问作者husam
相关产品推荐
相关产品推荐

