未定义的名称“上下文”(在 Flutter 导航中)

Posted

技术标签:

【中文标题】未定义的名称“上下文”(在 Flutter 导航中)【英文标题】:Undefined name 'context' (in Flutter Navigation) 【发布时间】:2020-10-26 12:02:40 【问题描述】:

所以我尝试使用 Navigator.push(不使用 NamedRoutes)从一个屏幕导航到另一个屏幕。但突然我收到了这个未定义名称“上下文”的错误。我想从“loading_screen.dart”导航到“context_screen.dart”。我不明白为什么我会遇到这个错误。

loading_screen.dart

class LoadingScreen extends StatefulWidget 

  String searchTerm;
  LoadingScreen(this.searchTerm);

  @override
  _LoadingScreenState createState() => _LoadingScreenState();



class _LoadingScreenState extends State<LoadingScreen> 

  @override
  void initState() 
    print("On Loading Screen");
    String searchTerm = widget.searchTerm;
    getMeaning(searchTerm);
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Center(
        child: SpinKitWave(
          color: kMainBlueColor,
          size: 70.0,
        ),
      ),
    );
  


void getMeaning(String searchTerm) async 
  print(searchTerm);
  // TODO: get the meaning of the search term.
  // TODO: Test without net and see background loading
  var searchContext;
  // var searchContext = await .....
  Navigator.push(context, MaterialPageRoute(builder: (context) 
    return ContextScreen(searchContext: searchContext);
  ));

context_screen.dart

class ContextScreen extends StatefulWidget 

  final searchContext;
  ContextScreen(this.searchContext);

  @override
  _ContextScreenState createState() => _ContextScreenState();


class _ContextScreenState extends State<ContextScreen> 
  @override
  Widget build(BuildContext context) 
    var searchContext = widget.searchContext;
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Align(
              alignment: Alignment.topLeft,
              child: FlatButton(
                onPressed: () 
                  int count = 0;
                  Navigator.of(context).popUntil((context) => count++ >= 2);
                ,
                child: Icon(
                  Icons.arrow_back_ios,
                  color: kMainBlueColor,
                  size: 50.0,
                ),
              ),
            ),
            Center(
              child: Text(
                searchContext
              ),
            )
          ],
        ),
      )
    );
  

我忽略了上面的 import 语句,但我已将它们添加到我的代码中。任何帮助,将不胜感激。提前致谢。

【问题讨论】:

你能显示整个错误语句吗? 编译器消息:lib/screens/loading_screen.dart:47:18:错误:找不到 Getter:'context'。 Navigator.push(context, MaterialPageRoute(builder: (context) ^^^^^^^ Target kernel_snapshot failed: Exception: Errors during snapshot creation: null build failed.FAILURE: Build failed with an exception. 【参考方案1】:

错误是因为您在initState 中调用了一个使用上下文的方法。context 仅在完成initState 后可用。

所以你可以调用didChangeDependencies中的方法,在initState之后立即调用。

了解更多didChangeDependencies:https://api.flutter.dev/flutter/widgets/State/didChangeDependencies.html

了解更多 StatefulWidget 生命周期:https://medium.com/flutter-community/widget-state-buildcontext-inheritedwidget-898d671b7956

【讨论】:

感谢您的帮助,但我之前尝试过,效果很好。代替 TODO,我必须进行 API 调用。因此我使它异步,但它仍然给出同样的问题。 把方法调用放到didChangeDependencies或者加一些延迟时间。 非常感谢您的跟进。但我得到一个编译时错误而不是运行时错误。因此,在这里添加一些延迟时间或调用 didChangeDependencies 可能不起作用。由于错误甚至在应用程序编译之前就显示出来。更新:我试过了,但错误仍然存​​在。【参考方案2】:

您可以在下面复制粘贴运行完整代码 您可以将getMeaning 移动到_LoadingScreenState 并使用addPostFrameCallback

代码sn-p

class _LoadingScreenState extends State<LoadingScreen> 
  void getMeaning(String searchTerm) async 
    print(searchTerm);
    // TODO: get the meaning of the search term.
    // TODO: Test without net and see background loading
    var searchContext = "";
    // var searchContext = await .....
    await Future.delayed(Duration(seconds: 5), () 
    );

    Navigator.push(context, MaterialPageRoute(builder: (context) 
      return ContextScreen(searchContext: searchContext);
    ));
  

  @override
  void initState() 
    print("On Loading Screen");
    String searchTerm = widget.searchTerm;

    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) 
      getMeaning(searchTerm);
    );
  

工作演示

完整代码

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

class LoadingScreen extends StatefulWidget 
  String searchTerm;
  LoadingScreen(this.searchTerm);

  @override
  _LoadingScreenState createState() => _LoadingScreenState();


class _LoadingScreenState extends State<LoadingScreen> 
  void getMeaning(String searchTerm) async 
    print(searchTerm);
    // TODO: get the meaning of the search term.
    // TODO: Test without net and see background loading
    var searchContext = "";
    // var searchContext = await .....
    await Future.delayed(Duration(seconds: 5), () 
    );

    Navigator.push(context, MaterialPageRoute(builder: (context) 
      return ContextScreen(searchContext: searchContext);
    ));
  

  @override
  void initState() 
    print("On Loading Screen");
    String searchTerm = widget.searchTerm;

    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) 
      getMeaning(searchTerm);
    );
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Center(
        child: SpinKitWave(
          color: Colors.blue,
          size: 70.0,
        ),
      ),
    );
  


class ContextScreen extends StatefulWidget 
  final searchContext;
  ContextScreen(this.searchContext);

  @override
  _ContextScreenState createState() => _ContextScreenState();


class _ContextScreenState extends State<ContextScreen> 
  @override
  Widget build(BuildContext context) 
    var searchContext = widget.searchContext;
    return Scaffold(
        body: SafeArea(
      child: Column(
        children: <Widget>[
          Align(
            alignment: Alignment.topLeft,
            child: FlatButton(
              onPressed: () 
                int count = 0;
                Navigator.of(context).popUntil((context) => count++ >= 2);
              ,
              child: Icon(
                Icons.arrow_back_ios,
                color: Colors.blue,
                size: 50.0,
              ),
            ),
          ),
          Center(
            child: Text(searchContext),
          )
        ],
      ),
    ));
  


void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: LoadingScreen(searchTerm: "test"),
    );
  

【讨论】:

以上是关于未定义的名称“上下文”(在 Flutter 导航中)的主要内容,如果未能解决你的问题,请参考以下文章

导航未定义名称上下文

颤振导航未定义的“上下文”

颤振未定义的名称“上下文”。尝试将名称更正为已定义的名称,或定义名称

即使在重新启动 IDE 后,FLUTTER 中的未定义名称“http”

Dart/Flutter 不使用 Inkwell 和手势检测器更改页面

如何在 List 小部件 Flutter 中无上下文导航