Flutter中点击ListTile后如何获取并展示Firestore指定单文档内容
修复方案
核心错误原因
- pageShow类构造参数语法错误,未正确声明接收传入的Firestore文档对象
- pageShow中StreamBuilder配置错误:
get()为Future类型不能作为Stream使用,且未指定查询的目标文档,无法获取对应数据 - 列表页已经拿到了点击项的完整文档数据,详情页无需重复请求Firestore,直接使用传入数据即可
1. 列表页代码修改(仅调整类名符合Dart规范,跳转逻辑无需改动)
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'pageShow.dart'; // Dart类名需符合大驼峰命名规范 class TestPage extends StatelessWidget { const TestPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: StreamBuilder( stream: FirebaseFirestore.instance .collection('countries') .snapshots(), builder: (context, AsyncSnapshot<QuerySnapshot> querySnapshot) { if (querySnapshot.hasError) return const Text('加载出错'); if (querySnapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } final list = querySnapshot.data!.docs; return ListView.builder( itemBuilder: (context, index) { return Container( child: ListTile( title: Text(list[index]['name']), subtitle: Text(list[index]['description']), contentPadding: const EdgeInsets.all(20), leading: Image.network( list[index]['image'], height: 200, width: 80, fit: BoxFit.cover, ), onTap: () => Navigator.push( context, MaterialPageRoute( // 直接把当前点击的文档对象传入详情页 builder: (context) => PageShow(doc: list[index]), ), ), ), color: Colors.orangeAccent, ); }, itemCount: list.length, ); }, ), appBar: AppBar( centerTitle: true, backgroundColor: const Color.fromRGBO(255, 111, 82, 0.8), ), ); } }
2. 详情页pageShow代码修改
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; class PageShow extends StatelessWidget { // 声明接收传入的Firestore文档对象 final QueryDocumentSnapshot doc; const PageShow({Key? key, required this.doc}) : super(key: key); @override Widget build(BuildContext context) { // 直接读取传入的文档字段,无需二次请求Firestore return Scaffold( body: SingleChildScrollView( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( doc['name'], style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), const SizedBox(height: 16), Text( doc['description'], style: const TextStyle(fontSize: 20), ), const SizedBox(height: 16), const Text('特色美食:', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500)), Text( doc['cuisine'], style: const TextStyle(fontSize: 20), ), const SizedBox(height: 16), const Text('传统文化:', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500)), Text( doc['tradition'], style: const TextStyle(fontSize: 20), ) ], ), ), appBar: AppBar( centerTitle: true, backgroundColor: const Color.fromRGBO(255, 111, 82, 0.8), ), ); } }
可选优化(需要实时同步详情页数据时使用)
如果需要详情页数据实时跟随Firestore更新,可以改为传入文档ID监听单文档变化:
- 列表页跳转时传文档ID:
PageShow(docId: list[index].id) - 详情页配置Stream:
stream: FirebaseFirestore.instance.collection('countries').doc(docId).snapshots()
内容的提问来源于stack exchange,提问作者name__
相关产品推荐
相关产品推荐

