Una finestra di dialogo ha un ritardo di apertura, ottengo un errore quando navigo verso un'altra vista prima che la finestra venga generata. Come posso fare in modo che non venga generata?

voti
7

Sono nuovo a svolazzare.

Nel mio vero problema, il mio cliente si trova in luoghi dove è molto frequente che internet sia molto lento, quindi a volte si cerca di fare una richiesta web e questo può richiedere del tempo, quindi l'utente lascia lo schermo prima che la richiesta web sia completata. A volte la mia applicazione dopo aver completato una richiesta web genera un dialog. Quindi qui è dove si trova il mio problema, l'utente sta cercando di fare una richiesta web e mentre è fatto, lascia lo schermo e poi dialogviene generato.

Sto cercando di simulare questo problema con una delayche in seguito genera il dialog.

Non sto pensando ad alcuna strategia per porre fine alla richiesta web, quello che voglio è trovare un modo che una volta lasciato lo schermo, faccia sì che il dialogo non venga generato qualcosa come un dispose

Ho fatto un esempio in cui ho 2 schermi. Sul secondo schermo viene generata una finestra di dialogo con un ritardo di 5 secondi quando si fa clic sul pulsante. Se navigo verso un'altra schermata prima che la finestra di dialogo venga aperta, ottengo un errore. Presumo che questo si verifichi perché la vista è stata distrutta e quindi la finestra di dialogo non può essere aperta.

enter

Cosa posso fare per evitare l'errore quando il dialogo viene generato dopo essere stato in un'altra vista? se sono in un'altra vista NON VOGLIO che il dialogo venga generato.

id=pre-0
È pubblicato 07/06/2020 alle 07:55
fonte dall'utente
In altre lingue...                            


3 risposte

voti
0

Invece di Future.delayed, si dovrebbe usare Timer, che può essere annullato nel onDisposemetodo

Soluzione di lavoro:

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);
          },
        ),
      ),
    );
  }
}
Risposto il 09/06/2020 a 09:54
fonte dall'utente

voti
0

Prova questo codice

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

Spero che aiuti.

Risposto il 09/06/2020 a 08:52
fonte dall'utente

voti
0

utilizzare Globalkey in scaffold in poi controllare il contesto nel metodo di dialogo è esso != null poi eseguire il dialogo altrimenti non.....

  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();
            }
         });  
      }
Risposto il 11/06/2020 a 07:49
fonte dall'utente

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