Geoffrey Lee
Geoffrey Lee

Reputation: 407

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.

Upvotes: 5

Views: 33715

Answers (4)

jesus gilbert
jesus gilbert

Reputation: 17

Only add Navigator.pop(Get.overlayContext!, true);

Note: the symbol "!" is only if you're working with nullable type.

Upvotes: 0

Amer Al zibak
Amer Al zibak

Reputation: 1951

Try to use closeOverlays param this way :

Get.back(closeOverlays: true);

Upvotes: 3

ProZhar
ProZhar

Reputation: 1

I use it with bottomSheet(), but it will also work fine with Dialog. Just add an argument to Get.back(closeOverlays: true):

Get.bottomSheet(
  WillPopScope(
    onWillPop: () async {
      Get.back(closeOverlays: true);
      return false;
    },
    child: const QuestionWidget(),
);

Upvotes: 0

Omatt
Omatt

Reputation: 10473

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

Upvotes: 15

Related Questions