Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 对话框延迟打开,在生成对话框之前导航到另一个视图时出错。如何使其不生成?_Flutter - Fatal编程技术网

Flutter 对话框延迟打开,在生成对话框之前导航到另一个视图时出错。如何使其不生成?

Flutter 对话框延迟打开,在生成对话框之前导航到另一个视图时出错。如何使其不生成?,flutter,Flutter,我是个新手 在我真正的问题中,我的客户端经常处于互联网速度非常慢的位置,因此有时会尝试发出web请求,这可能需要时间,因此用户在完成web请求之前离开屏幕。有时,我的应用程序在完成web请求后会生成一个对话框。这就是我的问题所在,用户试图发出web请求,当请求完成时,他们离开屏幕,然后生成对话框 import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends Stat

我是个新手

在我真正的问题中,我的客户端经常处于互联网速度非常慢的位置,因此有时会尝试发出web请求,这可能需要时间,因此用户在完成web请求之前离开屏幕。有时,我的应用程序在完成web请求后会生成一个
对话框
。这就是我的问题所在,用户试图发出web请求,当请求完成时,他们离开屏幕,然后生成
对话框

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("main");
    return MaterialApp(title: 'Provider Example', initialRoute: '/', routes: {
      '/': (context) => Home(),
      'home': (context) => Home(),
      'dialogpage': (context) => Dialogpage(),
    });
  }
}

class Home extends StatelessWidget {
  Home() {
    print("home");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Text('home'),
        actions: <Widget>[
          IconButton(
            icon: const Icon(Icons.add_alert),
            tooltip: 'Show Snackbar',
            onPressed: () {
              Navigator.pushNamed(context, "dialogpage");
            },
          ),
        ],
      ),
      body: const Center(
        child: Text(
          'home',
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

class Dialogpage extends StatelessWidget {
  Dialogpage() {
    print("dialogpage");
  }

  dialog(BuildContext context) {
    Future.delayed(const Duration(seconds: 5), () {
      showDialog(
          context: context,
          barrierDismissible: false,
          builder: (context) {
            return AlertDialog(
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(20.0)),
              title: Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(19.0),
                    topRight: Radius.circular(19.0),
                  ),
                ),
                padding: EdgeInsets.symmetric(vertical: 10, horizontal: 5),
                child: Text(
                  'Error',
                  style: TextStyle(color: Colors.white),
                ),
              ),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Container(
                    margin: EdgeInsets.only(top: 20.0, bottom: 20.0),
                    child: Icon(
                      Icons.error,
                      size: 50,
                    ),
                  ),
                  Text("dialog"),
                ],
              ),
              titlePadding: EdgeInsets.all(0),
              actions: <Widget>[
                FlatButton(
                    child: Text('Aceptar'),
                    onPressed: () {
                      return Navigator.of(context).pop();
                    }),
              ],
            );
          });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('dialog'),
      ),
      body: Center(
        child: RaisedButton(
            child: Text("show dialog"),
            onPressed: () {
              dialog(context);
            }),
      ),
    );

  }
}
我试图用一个
延迟来模拟这个问题,该延迟随后会生成
对话框

我没有考虑任何结束web请求的策略,我想要的是找到一种方法,一旦我离开屏幕,就不会生成对话框,比如
dispose

我举了一个例子,我有两个屏幕。在第二个屏幕上,单击按钮时会生成一个延迟5秒的对话框。如果在打开对话框之前导航到另一个屏幕,则会出现错误。我假设发生这种情况是因为视图已被破坏,因此无法打开对话框

在另一个视图中生成对话框时,如何避免错误?如果我在另一个视图中,我不希望生成对话框

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("main");
    return MaterialApp(title: 'Provider Example', initialRoute: '/', routes: {
      '/': (context) => Home(),
      'home': (context) => Home(),
      'dialogpage': (context) => Dialogpage(),
    });
  }
}

class Home extends StatelessWidget {
  Home() {
    print("home");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Text('home'),
        actions: <Widget>[
          IconButton(
            icon: const Icon(Icons.add_alert),
            tooltip: 'Show Snackbar',
            onPressed: () {
              Navigator.pushNamed(context, "dialogpage");
            },
          ),
        ],
      ),
      body: const Center(
        child: Text(
          'home',
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

class Dialogpage extends StatelessWidget {
  Dialogpage() {
    print("dialogpage");
  }

  dialog(BuildContext context) {
    Future.delayed(const Duration(seconds: 5), () {
      showDialog(
          context: context,
          barrierDismissible: false,
          builder: (context) {
            return AlertDialog(
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(20.0)),
              title: Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(19.0),
                    topRight: Radius.circular(19.0),
                  ),
                ),
                padding: EdgeInsets.symmetric(vertical: 10, horizontal: 5),
                child: Text(
                  'Error',
                  style: TextStyle(color: Colors.white),
                ),
              ),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Container(
                    margin: EdgeInsets.only(top: 20.0, bottom: 20.0),
                    child: Icon(
                      Icons.error,
                      size: 50,
                    ),
                  ),
                  Text("dialog"),
                ],
              ),
              titlePadding: EdgeInsets.all(0),
              actions: <Widget>[
                FlatButton(
                    child: Text('Aceptar'),
                    onPressed: () {
                      return Navigator.of(context).pop();
                    }),
              ],
            );
          });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('dialog'),
      ),
      body: Center(
        child: RaisedButton(
            child: Text("show dialog"),
            onPressed: () {
              dialog(context);
            }),
      ),
    );

  }
}
导入“包装:颤振/材料.省道”;
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
印刷品(“主要”);
返回MaterialApp(标题:“提供程序示例”,初始路由:“/”,路由:{
“/”:(上下文)=>Home(),
“home”:(上下文)=>home(),
“dialogpage”:(上下文)=>dialogpage(),
});
}
}
类Home扩展了无状态小部件{
Home(){
打印(“主页”);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
背景颜色:Colors.white,
appBar:appBar(
标题:常量文本(“主页”),
行动:[
图标按钮(
图标:常量图标(图标。添加警报),
工具提示:“显示Snackbar”,
已按下:(){
Navigator.pushNamed(上下文,“dialogpage”);
},
),
],
),
正文:康斯特中心(
子:文本(
“家”,
样式:TextStyle(字体大小:24),
),
),
);
}
}
类Dialogpage扩展了无状态小部件{
Dialogpage(){
打印(“对话页”);
}
对话框(构建上下文){
未来。延迟(常数持续时间(秒:5),(){
显示对话框(
上下文:上下文,
禁止:错误,
生成器:(上下文){
返回警报对话框(
形状:圆形矩形边框(
边界半径:边界半径。圆形(20.0)),
标题:集装箱(
装饰:盒子装饰(
borderRadius:仅限borderRadius(
左上:半径。圆形(19.0),
右上角:圆形半径(19.0),
),
),
填充:边缘组。对称(垂直:10,水平:5),
子:文本(
“错误”,
样式:TextStyle(颜色:Colors.white),
),
),
内容:专栏(
mainAxisSize:mainAxisSize.min,
儿童:[
容器(
边距:仅限边集(顶部:20.0,底部:20.0),
子:图标(
错误,
尺码:50,
),
),
文本(“对话框”),
],
),
标题添加:所有边集(0),
行动:[
扁平按钮(
子项:文本('Aceptar'),
已按下:(){
返回Navigator.of(context.pop();
}),
],
);
});
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:常量文本(“对话框”),
),
正文:中(
孩子:升起按钮(
子项:文本(“显示对话框”),
已按下:(){
对话(上下文);
}),
),
);
}
}
试试这段代码

class Dialogpage extends StatelessWidget {
  ...
  Timer t;

  dialog(BuildContext context) {
    t = Timer(Duration(seconds: 5), () {
      showDialog(...);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('dialog'),
        leading: IconButton(
          icon: Icon(Icons.arrow_back, color: Colors.black),
          onPressed: () {
            t?.cancel();
            Navigator.of(context).pop();
          },
        ),
      ),
      body: Center(
        child: RaisedButton(
            child: Text("show dialog"),
            onPressed: () {
              dialog(context);
            }),
      ),
    );
  }
}

希望对您有所帮助。

您应该使用
定时器,而不是
未来延迟的
,可以通过
onDispose
方法取消定时器

工作解决方案:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("main");
    return MaterialApp(
      title: 'Provider Example',
      initialRoute: '/',
      routes: {
        '/': (context) => Home(),
        'home': (context) => Home(),
        'dialogpage': (context) => Dialogpage(),
      },
    );
  }
}

class Home extends StatelessWidget {
  Home() {
    print("home");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('home'),
        actions: <Widget>[
          IconButton(
            icon: const Icon(Icons.add_alert),
            tooltip: 'Show Snackbar',
            onPressed: () {
              Navigator.pushNamed(context, "dialogpage");
            },
          ),
        ],
      ),
      body: const Center(
        child: Text(
          'home',
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

class Dialogpage extends StatefulWidget {
  @override
  _DialogpageState createState() => _DialogpageState();
}

class _DialogpageState extends State<Dialogpage> {
  Timer _timer;

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  dialog(BuildContext context) {
    _timer = Timer(
      const Duration(seconds: 3),
      () {
        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (context) {
            return AlertDialog(
              shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
              title: Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(19.0),
                    topRight: Radius.circular(19.0),
                  ),
                ),
                padding: EdgeInsets.symmetric(vertical: 10, horizontal: 5),
                child: Text(
                  'Error',
                  style: TextStyle(color: Colors.white),
                ),
              ),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Container(
                    margin: EdgeInsets.only(top: 20.0, bottom: 20.0),
                    child: Icon(
                      Icons.error,
                      size: 50,
                    ),
                  ),
                  Text("dialog"),
                ],
              ),
              titlePadding: EdgeInsets.all(0),
              actions: <Widget>[
                FlatButton(
                  child: Text('Aceptar'),
                  onPressed: () {
                    return Navigator.of(context).pop();
                  },
                ),
              ],
            );
          },
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('dialog'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text("show dialog"),
          onPressed: () {
            dialog(context);
          },
        ),
      ),
    );
  }
}
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
印刷品(“主要”);
返回材料PP(
标题:“提供程序示例”,
initialRoute:“/”,
路线:{
“/”:(上下文)=>Home(),
“home”:(上下文)=>home(),
“dialogpage”:(上下文)=>dialogpage(),
},
);
}
}
类Home扩展了无状态小部件{
Home(){
打印(“主页”);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:常量文本(“主页”),
行动:[
图标按钮(
图标:常量图标(图标。添加警报),
工具提示:“显示Snackbar”,
已按下:(){
Navigator.pushNamed(上下文,“dialogpage”);
},
),
],
),
正文:康斯特中心(
子:文本(
“家”,
样式:TextStyle(字体大小:24),
),
),
);
}
}
类Dialogpage扩展StatefulWidget{
@凌驾
_DialogpageState createState()=>DialogpageState();
}
类_DialogpageState扩展状态{
定时器(u定时器),;
@凌驾
无效处置(){
_计时器?.cancel();
super.dispose();
}
对话框(构建上下文){