ダイアログのボタンを押した後、ロード画面を実行しようとしました。ダイアログのボタンを押した後、プログラムは最初にダイアログをポップし、次に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);
})));
}
}
主なエラーは、変数の命名にあります。からダイアログ関数を呼び出すとき
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]
コメントを追加