Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter close a Dialog inside a condition

Tags:

flutter

dart

I am trying to close a Dialog dynamically. What I am actually trying to do is to change the content of the dialog depending on the information I have at the moment.

Starts with loading info and no button and after a few seconds could be an error with the OK button to close the Dialog Box.

class Dialogs{
  loginLoading(BuildContext context, String type, String description){
    var descriptionBody;

    if(type == "error"){
      descriptionBody = CircleAvatar(
        radius: 100.0,
        maxRadius: 100.0,
        child: new Icon(Icons.warning),
        backgroundColor: Colors.redAccent,
      );
    } else {
      descriptionBody = new Center(
        child: new CircularProgressIndicator(),
      );
    }

    return showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context){
        return AlertDialog(
          title: descriptionBody,
          content: SingleChildScrollView(
            child: ListBody(
              children: <Widget>[
                Center(child: Text(description))
              ],
            ),
          ),
        );
      }
    );
  }
}

So after creating the instance os the dialog and opening it

Dialogs _dialog = new Dialogs();
_dialog.loginLoading(context, "loading", "loading...");

// Close the dialog code here
don't know how to do it

// Call again the AlertDialog with different content.
like image 458
Raffaele Colleo Avatar asked Jan 27 '23 07:01

Raffaele Colleo


2 Answers

https://docs.flutter.io/flutter/material/showDialog.html

The dialog route created by this method is pushed to the root navigator. If the application has multiple Navigator objects, it may be necessary to call Navigator.of(context, rootNavigator: true).pop(result) to close the dialog rather than just Navigator.pop(context, result).

So any one of the below should work for you

  • Navigator.of(context, rootNavigator: true).pop(result)
  • Navigator.pop(context, result)
like image 96
sreeramu Avatar answered Feb 07 '23 11:02

sreeramu


You don't need to close and reopen the dialog. Instead let flutter handle the dialog update. The framework is optimised for just that.

Here is a working example app that you can use as a starting point (just add your own Dialogs class):

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'MyApp',
      home: Login(
        child: Home(),
      ),
    );
  }
}

class Home extends StatefulWidget {
  final Dialogs dialog = Dialogs();
  @override
  State<StatefulWidget> createState() => HomeState();
}

class HomeState extends State<Home> {
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    Future.delayed(Duration(milliseconds: 50)).then((_) {
      widget.dialog.loginLoading(
        context,
        LoginStateProvider.of(context).type,
        LoginStateProvider.of(context).description,
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Updating Dialog'),
      ),
      body: Container(),
    );
  }
}

class Login extends StatefulWidget {
  final Widget child;
  Login({@required this.child});

  @override
  State<StatefulWidget> createState() => LoginState();
}

class LoginState extends State<Login> {
  String type = 'wait';
  String description = 'foo';

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    Future.delayed(Duration(milliseconds: 2000)).then((_) {
      setState(() {
        type = 'error';
        description = 'bar';
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return LoginStateProvider(widget.child, type, description);
  }
}

class LoginStateProvider extends InheritedWidget {
  final String type;
  final String description;
  LoginStateProvider(Widget child, this.type, this.description)
      : super(child: child);
  @override
  bool updateShouldNotify(LoginStateProvider old) {
    return type != old.type || description != old.description;
  }

  static LoginStateProvider of(BuildContext context) =>
      context.inheritFromWidgetOfExactType(LoginStateProvider);
}
like image 32
Soundbytes Avatar answered Feb 07 '23 11:02

Soundbytes