Диалог имеет задержку на открытие, я получаю ошибку при переходе к другому виду до того, как диалог будет создан. Как сделать так, чтобы он не был сгенерирован?

голоса
5

Я новичок в трепетах.

В моей настоящей проблеме, мой клиент находится в местах, где это очень часто, что интернет очень медленно, так что иногда делается попытка сделать веб-запрос, и это может занять время, так что пользователь покидает экран, прежде чем веб-запрос будет завершен. Иногда мое приложение после завершения веб-запроса генерирует adialog. Так что вот где моя проблема лежит, пользователь пытается сделать веб-запрос, и в то время как это сделано, они покидают экран, а затем генерируется.dialog

Я пытаюсь смоделировать эту проблему с тем, delayчто позже генерирует dialog.

Я не думаю ни о какой стратегии, чтобы закончить веб запрос, что я хочу, чтобы найти способ, который, как только я покинул экран, заставляет диалог не быть сгенерированным что-то вроде dispose

Я сделал пример, где у меня 2 экрана. На втором экране создается диалог с задержкой 5 секунд при нажатии кнопки. Если я перейду на другой экран до того, как диалог будет открыт, я получу ошибку. Я предполагаю, что это происходит потому, что вид был уничтожен, и поэтому диалог не может быть открыт.

enter

Что я могу сделать, чтобы избежать ошибки, когда диалоговое окно генерируется после того, как я нахожусь в другом представлении? если я нахожусь в другом представлении, я НЕ ХОЧУ, чтобы диалоговое окно генерировалось.

id=до 0
Задан 07/06/2020 в 07:55
источник пользователем
На других языках...                            


3 ответов

голоса
0

Вместо этогоFuture.delayed, вы должны использоватьTimer, что может быть отменено 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);
          },
        ),
      ),
    );
  }
}
Ответил 09/06/2020 в 09:54
источник пользователем

голоса
0

Попробуйте этот код

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);
            }),
      ),
    );
  }
}

Надеюсь, это поможет.

Ответил 09/06/2020 в 08:52
источник пользователем

голоса
0

используйте Globalkey в строительных лесах, а затем проверьте контекст в диалоговом методе - это != null тогда запустите диалог, иначе....

  GlobalKey _scafolldKey = GlobalKey<ScaffoldState>();

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

    dialog(BuildContext context) {
        Future.delayed(const Duration(seconds: 2), () {
          if(_scafolldKey.currentContext !=null){
          showDialog();
            }
         });  
      }
Ответил 11/06/2020 в 07:49
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more