【问题标题】:Flutter Unhandled Exception: Looking up a deactivated widget's ancestor is unsafeFlutter Unhandled Exception:查找已停用小部件的祖先是不安全的
【发布时间】:2021-06-03 06:37:59
【问题描述】:

按下对话框上的按钮后,我试图做一个加载屏幕。 按下对话框上的按钮后,程序将首先弹出对话框,然后显示一个 WillPopScope 对象 2 秒,然后弹出加载屏幕。 代码如下:

onPressed: () async {
  Navigator.pop(context);
  loadingScreen(context);
  await Future.delayed(Duration(seconds: 2));
  Navigator.pop(context);
},

但它显示了以下错误:

E/flutter (14960): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
E/flutter (14960): At this point the state of the widget's element tree is no longer stable.
E/flutter (14960): To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.

经过一番研究,我认为这个错误是由不存在的弹出上下文引起的,所以我尝试在延迟后同时弹出对话框和加载屏幕

onPressed: () async {
  loadingScreen(context);
  await Future.delayed(Duration(seconds: 2));
  Navigator.pop(context);
  Navigator.pop(context);
},

虽然它有效,但这并不是我想要的,而且我真的很困惑为什么会这样。请问谁能给我解释一下发生了什么,有什么办法解决吗?

完整代码:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Future<void> loadingScreen(BuildContext context) async {
    return showDialog(
        context: context,
        builder: (context) {
          return WillPopScope(
              onWillPop: () => Future.value(false), child: Text(''));
        });
  }

  dialog(BuildContext context) {
    return showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          content: Text('Show Loading Screen'),
          actions: <Widget>[
            TextButton(
              child: Text('Okay'),
              onPressed: () async {
                Navigator.pop(context);
                loadingScreen(context);
                await Future.delayed(Duration(seconds: 2));
                Navigator.pop(context);
              },
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Demo'),
        ),
        body: Center(
            child: TextButton(
                child: Text('Show Dialog'),
                onPressed: () {
                  dialog(context);
                })));
  }
}

【问题讨论】:

    标签: flutter


    【解决方案1】:

    您的主要错误在于变量的命名:当您从以下位置调用对话框函数时

    Widget build(BuildContext context)...
    

    您将 BuildContext 作为该函数的参数,并将该上下文用于对话框。让我重命名您的变量,以便您更好地理解:

    dialog(BuildContext contextFromBuild) {  //this is the argument to the function
        return showDialog(
          context: contextFromBuild,
          builder: (BuildContext contextInsideDialog) { //new BuildContext inside the dialog
            return AlertDialog(
              content: Text('Show Loading Screen'),
              actions: <Widget>[
                TextButton(
                  child: Text('Okay'),
                  onPressed: () async {
                    Navigator.pop(contextInsideDialog);
                    loadingScreen(contextInsideDialog);
                    await Future.delayed(Duration(seconds: 2));
                    Navigator.pop(contextInsideDialog);
                  },
                ),
              ],
            );
          },
        );
    

    如您所见,您正在弹出 contextInsideDialog 但随后尝试访问它:

    loadingScreen(contextInsideDialog);
    

    这会导致错误,因为您已经弹出了该上下文 (contextInsideDialog)。只需通过重命名变量来修复它。

    【讨论】:

    • 非常感谢您的帮助。但它仍然给我同样的错误,直到我将你的代码修改为: loadingScreen(contextFromBuild);第二个 pop : Navigator.pop(contextFromBuild);无论如何,非常感谢您的解释,它非常有帮助!
    猜你喜欢
    • 2020-08-08
    • 2021-04-29
    • 2021-07-28
    • 2020-06-19
    • 2021-11-15
    • 2020-12-26
    • 2022-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多