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

Flutter世界时钟项目Navigator.pop报context未定义错误求助

解决Flutter中Navigator.pop的context未定义问题

我正在跟着教程开发Flutter「世界时钟」项目,作为新手碰到了一个错误:在Choose页面使用Navigator.pop时提示Undefined name 'context'。

项目流程是:Loading页面通过Navigator.pushReplacementNamed初始化Home页面;我想在Choose页面用ListView.builder创建新的WorldTime实例,再通过Navigator.pop把数据返回上一页,但报错了。


相关代码

Choose Page

import 'package:flutter/material.dart';
import 'package:world_time/services/world_time.dart';

class ChooseLocation extends StatefulWidget {
  const ChooseLocation({Key? key}) : super(key: key);

  @override
  State<ChooseLocation> createState() => _ChooseLocationState();
}
List<WorldTime> locations = [
  WorldTime('Lagos', 'time', 'nigeria.png', 'Africa/Lagos', true),
  WorldTime('Islamabad', 'time', 'pakistan.png', 'Asia/Islamabad', true),
  WorldTime('Lund', 'time', 'sweden.png', 'Europe/Lund', true),
  WorldTime('Birmingham', 'time', 'uk.png', 'Europe/Birmingham', true),
  WorldTime('London', 'time', 'uk.png' , 'Europe/London', true),
  WorldTime('Athens', 'time', 'greece.png', 'Europe/Berlin', true),
  WorldTime('Cairo', 'time', 'egypt.png', 'Africa/Cairo', true),
  WorldTime('Nairobi', 'time', 'kenya.png', 'Africa/Nairobi', true),
  WorldTime('Chicago', 'time', 'usa.png', 'America/Chicago', true),
  WorldTime('New York', 'time', 'usa.png', 'America/New_York', true),
  WorldTime('Seoul', 'time', 'south_korea.png', 'Asia/Seoul', true),
  WorldTime('Jakarta', 'time', 'indonesia.png', 'Asia/Jakarta', true),
];

void updateTime(index) async {
  WorldTime instance = locations[index];
  await instance.getTime();

// 错误发生在这一行:Undefined name 'context'
  Navigator.pop(context, {
    'location': instance.location,
    'flag': instance.flag,
    'time': instance.time,
    'isDayTime': instance.isDayTime});
}

class _ChooseLocationState extends State<ChooseLocation> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blue[800],
        title: const Text('Choose A Location'),
        centerTitle: true,
        elevation: 0,
      ),
      body: ListView.builder(itemCount:locations.length,
      itemBuilder: (context, index){
        return Padding(
          padding: const EdgeInsets.symmetric(vertical: 1.0, horizontal: 4.0),
          child: Card(
            child: ListTile(
              onTap: (){
                updateTime(index);
              },
                title: Text(locations[index].location),
              leading: CircleAvatar(
                backgroundImage: AssetImage('assets/${locations[index].flag}'),
              ),
            ),
          ),
        );
      }
      ),
    );
  }
}

Loading Page

import 'package:flutter/material.dart';
import 'package:world_time/services/world_time.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';


class Loading extends StatefulWidget {
  const Loading({Key? key}) : super(key: key);

  @override
  State<Loading> createState() => _LoadingState();
}

class _LoadingState extends State<Loading> {

  void setupWorldTime() async {
    WorldTime instance = WorldTime('Berlin', 'time', 'germany.png', 'Europe/Berlin', true);
    await instance.getTime();
    Navigator.pushReplacementNamed(context,'/home', arguments: {
      'location': instance.location,
      'flag': instance.flag, 
      'time': instance.time, 
      'isDayTime': instance.isDayTime
    });
  }

  @override
  void initState(){
    super.initState();
    setupWorldTime();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.lightBlue,
      body:Center(
      child: SpinKitFadingCircle(
      itemBuilder: (BuildContext context, int index) {
    return DecoratedBox(
    decoration: BoxDecoration(
    color: index.isEven ? Colors.white : Colors.lightBlue,
    ),
    );
    },
    ),
      ),
    );
  }
}

Home Page

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {

  Map data = {};

  @override
  Widget build(BuildContext context) {

    data = data.isNotEmpty ? data : ModalRoute.of(context)?.settings.arguments as     Map<dynamic,dynamic>;
    print(data);

    String bgImage = (data?['isDayTime'] ?? false) ?'day.png' : 'night.png';
    Color bgColor = (data?['isDayTime'] ?? false) ? Colors.lightBlue : Colors.blue;

    return Scaffold(
      backgroundColor: bgColor,
      body: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage('assets/$bgImage'),
              fit:BoxFit.cover,
          ),
        ),
        child: Padding(
          padding: const EdgeInsets.fromLTRB(0,120,0,0),
          child: SafeArea(
            child: Column(
              children: [
            TextButton.icon(onPressed: ()async {
              dynamic result = await Navigator.pushNamed(context, '/location');
              setState(() {
                data = {
                  'time': result['time'],
                  'location': result['location'],
                  'isDayTime': result['isDayTime'],
                  'flag': result['flag']
                };
              });
            }, icon: const Icon(Icons.edit_location), label: const Text('Edit Location'),
              style: TextButton.styleFrom(
               foregroundColor: Colors.grey[300],
              ),
            ),
                SizedBox(height: 20.0),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(data['location'],
                      style: TextStyle(fontSize: 28, letterSpacing: 2, color: Colors.white),
                ),
                  ],
                ),
                SizedBox(height: 20),
                Text(data['time'],
                style: TextStyle(fontSize: 66, color: Colors.white),
                ),
              ],
            ),
          ),
        ),
      ),
      );
  }
}

问题原因

updateTime是全局函数,无法访问State类中的context对象。Flutter的context仅能在Widget树的上下文范围内使用,全局函数不在这个有效范围内。

解决方法

方法1:将updateTime移到State类内部

把updateTime改为_ChooseLocationState的类方法,直接访问类内的context:

class _ChooseLocationState extends State<ChooseLocation> {
  // 移到State类内部
  void updateTime(int index) async {
    WorldTime instance = locations[index];
    await instance.getTime();

    Navigator.pop(context, {
      'location': instance.location,
      'flag': instance.flag,
      'time': instance.time,
      'isDayTime': instance.isDayTime
    });
  }

  @override
  Widget build(BuildContext context) {
    // 其余代码不变
  }
}

同时删除原来的全局updateTime函数。

方法2:给全局updateTime传入context参数

如果要保留全局函数,调用时把itemBuilder中的context传进去:

// 修改全局函数,添加context参数
void updateTime(BuildContext context, int index) async {
  WorldTime instance = locations[index];
  await instance.getTime();

  Navigator.pop(context, {
    'location': instance.location,
    'flag': instance.flag,
    'time': instance.time,
    'isDayTime': instance.isDayTime
  });
}

// 在ListTile的onTap中传入context
onTap: (){
  updateTime(context, index);
},

推荐方法1,它更符合Flutter代码组织规范,避免全局函数带来的潜在问题。

内容的提问来源于stack exchange,提问作者HungerMadra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:05:17