Search code examples
flutterflutter-getx

Flutter dismiss selected dialog with Getx


I am using flutter for quite some time and recently use Get to implement state management. I am facing a problem when opening a loading dialog 1st and then message dialog. Then I want to dismiss the loading dialog, but the message dialog is the one that keep dismiss.

import 'package:flutter/material.dart';
import 'package:get/get.dart';

class HomeController extends GetxController {

  Future<void> openAndCloseLoadingDialog() async {
    showDialog(
      context: Get.overlayContext,
      barrierDismissible: false,
      builder: (_) => WillPopScope(
        onWillPop: () async => false,
        child: Center(
          child: SizedBox(
            width: 60,
            height: 60,
            child: CircularProgressIndicator(
              strokeWidth: 10,
            ),
          ),
        ),
      ),
    );

    await Future.delayed(Duration(seconds: 3));

    Get.dialog(
      AlertDialog(
        title: Text("This should not be closed automatically"),
        content: Text("This should not be closed automatically"),
        actions: <Widget>[
          FlatButton(
            child: Text("CLOSE"),
            onPressed: () {
              Get.back();
            },
          )
        ],
      ),
      barrierDismissible: false,
    );

    await Future.delayed(Duration(seconds: 3));

    Navigator.of(Get.overlayContext).pop();
  }
}

The above code dismisses the 2nd dialog, not the 1st dialog which what I want. Can anyone give advice on this matter.


Solution

  • The reason why the AlertDialog is being dismissed instead of CircularProgressIndicator is because AlertDialog is on the top of the stack. What you can do here is to call Navigator.of(Get.overlayContext).pop(); to dismiss CircularProgressIndicator prior to displaying the AlertDialog.

    Demo

    Sample code based from the snippets provided.

    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return GetMaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
      final HomeController c = Get.put(HomeController());
    
      void _incrementCounter() {
        c.openAndCloseLoadingDialog();
        // setState(() {
        //   _counter++;
        // });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }
    
    class HomeController extends GetxController {
    
      Future<void> openAndCloseLoadingDialog() async {
        showDialog(
          context: Get.overlayContext,
          barrierDismissible: false,
          builder: (_) => WillPopScope(
            onWillPop: () async => false,
            child: Center(
              child: SizedBox(
                width: 60,
                height: 60,
                child: CircularProgressIndicator(
                  strokeWidth: 10,
                ),
              ),
            ),
          ),
        );
    
        await Future.delayed(Duration(seconds: 3));
        // Dismiss CircularProgressIndicator
        Navigator.of(Get.overlayContext).pop();
    
        Get.dialog(
          AlertDialog(
            title: Text("This should not be closed automatically"),
            content: Text("This should not be closed automatically"),
            actions: <Widget>[
              FlatButton(
                child: Text("CLOSE"),
                onPressed: () {
                  Get.back();
                },
              )
            ],
          ),
          barrierDismissible: false,
        );
    
        // await Future.delayed(Duration(seconds: 3));
        // Navigator.of(Get.overlayContext).pop();
      }
    }