Flutter Firebase列表项InkWell跳转context未定义及详情页传参问题
问题解决:修复Flutter中「Undefined name 'context'」错误并实现医生详情页跳转
问题描述
从Firebase获取数据生成医生列表,希望点击列表项跳转至对应详情页展示专属信息,但出现「Undefined name 'context'」错误(第51行),同时需解决详情页数据传递问题。原代码如下:
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'AddDoctor.dart'; class HospitalDoctorList extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFD9E4EE), appBar: AppBar( title: const Text('Doctor List'), ), body: StreamBuilder<List<Doctors>>( stream: readUsers(), builder: (context, snapshot) { if (snapshot.hasError) { return Text('Something went wrong! ${snapshot.error}'); } else if (snapshot.hasData) { final doctors = snapshot.data!; return ListView( children: doctors.map(buildDoctors).toList(), ); } else { return const Center( child: CircularProgressIndicator(), ); } }), floatingActionButton: FloatingActionButton( backgroundColor: Colors.blue, onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => AddDoctor(), ), ); }, child: const Icon(Icons.add), ), ); } Widget buildDoctors(Doctors doctors) => SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(10), child: InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => AddDoctor(), ), ); }, child: Container( height: 120, decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: Colors.white60, ), child: Row( //mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Image.asset( 'assets/PKC-Pics_0.jpg', height: double.infinity, ), const SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( (doctors.name), style: const TextStyle( fontSize: 28, fontWeight: FontWeight.bold, ), ), Text( doctors.specialist, style: const TextStyle( fontSize: 20, //fontWeight: FontWeight.bold, ), ), Text( doctors.hospital, style: const TextStyle( fontSize: 20, //fontWeight: FontWeight.bold, ), ), Text( '${doctors.age}', style: const TextStyle( fontSize: 20, //fontWeight: FontWeight.bold, ), ), ], ), ], ), ), ), ), ); Stream<List<Doctors>> readUsers() => FirebaseFirestore.instance .collection('DoctorList') .snapshots() .map((snapshot) => snapshot.docs.map((doc) => Doctors.fromJson(doc.data())).toList()); } class Doctors { String id; final String name; final int age; final String hospital; final String specialist; Doctors({ this.id = '', required this.name, required this.age, required this.hospital, required this.specialist, }); static Doctors fromJson(Map<String, dynamic> json) => Doctors( id: json['id'], name: json['name'], age: json['age'], hospital: json['hospital'], specialist: json['specialist'], ); }
解决方案
1. 修复「Undefined name 'context'」错误
错误原因是buildDoctors方法无法直接访问context,需将context作为参数传入:
- 修改
StreamBuilder中生成列表的代码:return ListView( children: doctors.map((doctor) => buildDoctors(context, doctor)).toList(), ); - 更新
buildDoctors方法的签名,添加context参数:Widget buildDoctors(BuildContext context, Doctors doctors) => SingleChildScrollView(...)
2. 实现详情页数据传递与跳转
首先创建医生详情页DoctorDetailPage,接收Doctors对象并展示信息:
class DoctorDetailPage extends StatelessWidget { final Doctors doctor; const DoctorDetailPage({super.key, required this.doctor}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(doctor.name)), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('姓名: ${doctor.name}', style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), const SizedBox(height: 10), Text('科室: ${doctor.specialist}', style: const TextStyle(fontSize: 20)), const SizedBox(height: 10), Text('医院: ${doctor.hospital}', style: const TextStyle(fontSize: 20)), const SizedBox(height: 10), Text('年龄: ${doctor.age}', style: const TextStyle(fontSize: 20)), ], ), ), ); } }
然后修改InkWell的onTap回调,跳转到详情页并传递当前医生数据:
onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => DoctorDetailPage(doctor: doctors), ), ); },
完整修改后的核心代码片段
// 在HospitalDoctorList的build方法中 return ListView( children: doctors.map((doctor) => buildDoctors(context, doctor)).toList(), ); // buildDoctors方法 Widget buildDoctors(BuildContext context, Doctors doctors) => SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(10), child: InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => DoctorDetailPage(doctor: doctors), ), ); }, // 其余容器代码不变 ), ), );
内容的提问来源于stack exchange,提问作者root1_2
相关产品推荐
相关产品推荐

