Un diálogo tiene un retraso para abrirse, obtengo un error al navegar a otra vista antes de que se genere el diálogo. ¿Cómo puedo hacer que no se genere?

votos
7

Soy nuevo en el mundo del revoloteo.

En mi verdadero problema, mi cliente está en lugares donde es muy frecuente que Internet sea muy lenta, así que a veces se intenta hacer una petición web y esto puede llevar tiempo, por lo que el usuario abandona la pantalla antes de que se complete la petición web. A veces mi aplicación después de completar una solicitud web genera unadialog. Así que aquí es donde está mi problema, el usuario está tratando de hacer una solicitud web y mientras se hace, sale de la pantalla y luego la dialoggenera.

Estoy tratando de simular este problema con una delayque luego genera la dialog.

No estoy pensando en ninguna estrategia para terminar la petición de la web, lo que quiero es encontrar una manera de que una vez que salga de la pantalla, haga que el diálogo no se genere algo como un dispose

Hice un ejemplo donde tengo 2 pantallas. En la segunda pantalla se genera un diálogo con un retardo de 5 segundos cuando se pulsa el botón. Si navego a otra pantalla antes de que el diálogo se abra, obtengo un error. Asumo que esto ocurre porque la vista fue destruida y por lo tanto el diálogo no puede ser abierto.

enter

¿Qué puedo hacer para evitar el error cuando el diálogo se genera después de estar en otra vista? Si estoy en otra vista NO QUIERO que el diálogo se genere.

id=pre-0
Publicado el 07/06/2020 a las 07:55
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
0

En lugar de Future.delayed, usted debe utilizar Timer, que puede ser cancelado en onDisposeel método

Solución de trabajo:

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);
          },
        ),
      ),
    );
  }
}
Respondida el 09/06/2020 a las 09:54
fuente por usuario

votos
0

Prueba este código

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

Espero que ayude.

Respondida el 09/06/2020 a las 08:52
fuente por usuario

votos
0

usa Globalkey en el andamiaje y luego comprueba el contexto en el método de diálogo, ¿está nulo? ...entonces ejecuta el diálogo, de lo contrario no...

  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();
            }
         });  
      }
Respondida el 11/06/2020 a las 07:49
fuente por usuario

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