Flutter Unhandled Exception:非アクティブ化されたウィジェットの祖先を検索することは安全ではありません

qwea

ダイアログのボタンを押した後、ロード画面を実行しようとしました。ダイアログのボタンを押した後、プログラムは最初にダイアログをポップし、次に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);
                })));
  }
}
lrsvmb

主なエラーは、変数の命名にあります。からダイアログ関数を呼び出すとき

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)をポップしているため、エラーが発生します。変数の名前を変更して修正するだけです。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ