Ein Dialog hat eine Verzögerung beim Öffnen, ich erhalte einen Fehler, wenn ich zu einer anderen Ansicht navigiere, bevor der Dialog generiert wird. Wie kann ich dafür sorgen, dass der Dialog nicht generiert wird?

stimmen
7

Ich bin neu im Flattern.

Mein eigentliches Problem besteht darin, dass sich mein Klient an Orten befindet, an denen das Internet sehr häufig sehr langsam ist, so dass manchmal versucht wird, eine Web-Anfrage zu stellen, und das kann einige Zeit dauern, so dass der Benutzer den Bildschirm verlässt, bevor die Web-Anfrage abgeschlossen ist. Manchmal erzeugt meine Anwendung nach dem Abschließen einer Webanfrage ein dialog... Hier liegt also mein Problem, der Benutzer versucht, eine Webanfrage zu stellen, und während er dies tut, verlässt er den Bildschirm, und dann wird das dialoggeneriert.

Ich versuche, dieses Problem mit einer delayzu simulieren, die später die dialog.

Ich denke nicht an eine Strategie, um die Webanfrage zu beenden, sondern ich möchte einen Weg finden, der bewirkt, dass der Dialog nicht generiert wird, sobald ich den Bildschirm verlasse, so etwas wie eine dispose

Ich habe ein Beispiel gemacht, wo ich 2 Bildschirme habe. Auf dem zweiten Bildschirm wird ein Dialog mit einer Verzögerung von 5 Sekunden erzeugt, wenn die Schaltfläche angeklickt wird. Wenn ich zu einem anderen Bildschirm navigiere, bevor der Dialog geöffnet wird, erhalte ich einen Fehler. Ich nehme an, dies geschieht, weil die Ansicht zerstört wurde und der Dialog daher nicht geöffnet werden kann.

enter

Was kann ich tun, um den Fehler zu vermeiden, wenn der Dialog generiert wird, nachdem ich mich in einer anderen Ansicht befinde? wenn ich mich in einer anderen Ansicht befinde, möchte ich NICHT, dass der Dialog generiert wird.

id=vor 0
Veröffentlicht am 07/06/2020 um 07:55
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
0

Anstelle von Future.delayed, sollten Sie , verwendenTimer, die in onDisposeder Methode abgebrochen werden kann

Funktionierende Lösung:

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);
          },
        ),
      ),
    );
  }
}
Beantwortet am 09/06/2020 um 09:54
quelle vom benutzer

stimmen
0

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

Ich hoffe, es hilft.

Beantwortet am 09/06/2020 um 08:52
quelle vom benutzer

stimmen
0

verwenden Sie Globalkey im Gerüst in und überprüfen Sie dann den Kontext in der Dialogmethode ist es != null dann Dialog ausführen, sonst nicht.....

  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();
            }
         });  
      }
Beantwortet am 11/06/2020 um 07:49
quelle vom benutzer

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