loading_alert_dialog

Customizable AlertDialog that allows running a computation while blocking the app like a normal showDialog without using the approach of using a Stack/Overlay widget.

Getting Started

This package exposes one main method, which is showLoadingDialog with similar implementation of normal showDialog or showCupertinoDialog. Optionally, calling setDefaultLoadingWidget allows settings what Widget to display during the Loading phase.

How-to-use example:

showLoadingDialog<int>(
  context: context,
  builder: (context) => Card(
    child: Padding(
      padding: const EdgeInsets.all(24.0),
      child: Column(
        children: <Widget>[
          CircularProgressIndicator(),
          Text("Please wait..."),
        ],
        mainAxisSize: MainAxisSize.min,
      ),
    ),
    color: Colors.white,
  ),
  computation: (pop, err) {
    Future.delayed(
      Duration(seconds: 3,), () {
        final randomNumber = Random().nextInt(100);
        pop(randomNumber);
      },
    );
  },
  onPop: (number) {
    if (number != null) {
      setState(() {
        _randomNumber = number;
      });
    }
  },
);

The builder may returns any Widget eligible to be used as an "AlertDialog". The sample code above shows a simple Card with a Text and CircularProgressIndicator for 3 seconds, then pops out a random number, closing the "AlertDialog", then displaying the popped number into the view.

Cheatsheet

  • pop closes the "AlertDialog" and pops and returns a specific type value.
  • err closes the "AlertDialog" and pops NOTHING and returns an optional, any kind of value, indicating there is an error.
  • Omitting the computation parameter or not calling any of pop or err will cause the "AlertDialog" to be shown indefinitely.

Full Example Code

void main() {
  runApp(
    LoadingAlertDialogExampleApp(),
  );
}

class LoadingAlertDialogExampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      color: Colors.blue,
      home: LoadingAlertDialogExample(),
    );
  }
}

class LoadingAlertDialogExample extends StatefulWidget {
  @override
  _LoadingAlertDialogExampleState createState() => _LoadingAlertDialogExampleState();
}

class _LoadingAlertDialogExampleState extends State<LoadingAlertDialogExample> {

  int _randomNumber = 0;

  void _showAlert() {
    showLoadingDialog<int>(
      context: context,
      builder: (context) => Card(
        child: Padding(
          padding: const EdgeInsets.all(24.0),
          child: Column(
            children: <Widget>[
              CircularProgressIndicator(),
              Text("Please wait..."),
            ],
            mainAxisSize: MainAxisSize.min,
          ),
        ),
        color: Colors.white,
      ),
      computation: (pop, err) {
        Future.delayed(
          Duration(seconds: 3,), () {
            final randomNumber = Random().nextInt(100);
            pop(randomNumber);
          },
        );
      },
      onPop: (number) {
        if (number != null) {
          setState(() {
            _randomNumber = number;
          });
        }
      },
    );
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text("Loading Alert Dialog Example"),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(24.0),
          child: Column(
            children: <Widget>[
              Text("Random Number: $_randomNumber"),
              RaisedButton(
                child: Text("Show Alert"),
                onPressed: _showAlert,
              ),
            ],
            mainAxisSize: MainAxisSize.min,
          ),
        ),
      ),
    );
  }
}

Libraries

loading_alert_dialog