Un dialogue a un délai pour s'ouvrir, j'obtiens une erreur lorsque je navigue vers une autre vue avant que le dialogue ne soit généré. Comment puis-je faire en sorte qu'il ne soit pas généré ?

voix
7

Je suis novice en matière de floutage.

Dans mon vrai problème, mon client se trouve dans des endroits où il est très fréquent que l'internet soit très lent, donc parfois une tentative est faite pour faire une requête web et cela peut prendre du temps, donc l'utilisateur quitte l'écran avant que la requête web ne soit terminée. Il arrive que mon application génère une demande web après avoir terminé une demande webdialog. C'est donc là que se situe mon problème : l'utilisateur essaie de faire une demande web et pendant qu'il la fait, il quitte l'écran et la demande dialogest générée.

J'essaie de simuler ce problème avec une application delayqui génère ensuite le fichier dialog.

Je ne pense à aucune stratégie pour mettre fin à la requête web, ce que je veux c'est trouver un moyen qui, une fois que je quitte l'écran, fasse en sorte que le dialogue ne soit pas généré quelque chose comme un dispose

J'ai fait un exemple où j'ai 2 écrans. Sur le deuxième écran, un dialogue est généré avec un délai de 5 secondes lorsque le bouton est cliqué. Si je navigue vers un autre écran avant que le dialogue ne soit ouvert, j'obtiens une erreur. Je suppose que cela se produit parce que la vue a été détruite et que le dialogue ne peut donc pas être ouvert.

enter

Que puis-je faire pour éviter l'erreur lorsque le dialogue est généré après avoir été dans une autre vue ? Si je suis dans une autre vue, je NE VEUX PAS que le dialogue soit généré.

id=pre-0
Créé 07/06/2020 à 07:55
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
0

Au lieu de Future.delayed, vous devriez utiliser Timer, qui peut être annulé dans la onDisposeméthode

Solution de travail :

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);
          },
        ),
      ),
    );
  }
}
Créé 09/06/2020 à 09:54
source utilisateur

voix
0

Essayez ce code

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

J'espère que cela vous aidera.

Créé 09/06/2020 à 08:52
source utilisateur

voix
0

utilisez Globalkey dans l'échafaudage puis vérifiez le contexte dans la méthode de dialogue : est-ce != null puis lancer le dialogue sinon ne...

  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();
            }
         });  
      }
Créé 11/06/2020 à 07:49
source utilisateur

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