You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:10:33