simple_loading_dialog
A simple full-screen loading dialog for Flutter.
Features
- Simple full-screen loading dialog.
- Blocks user input while waiting for a
Future
to complete. - Rethrows exceptions on error.
- Customizable dialog appearance.
- Returns the result of the
Future
.
Demo
Installation
To use this package, add simple_loading_dialog
as a dependency in your pubspec.yaml
file.
Usage
Showing the dialog
To show the dialog, use the showSimpleLoadingDialog
function:
final result = await showSimpleLoadingDialog<String>(
context: context,
future: myFutureFunction,
);
This will display a full-screen progress dialog while waiting for the myFutureFunction
to complete. Once the Future
completes, the result will be returned, and the dialog will be dismissed.
Customizing the appearance
The appearance of the dialog can be customized by passing a dialogBuilder
:
await showSimpleLoadingDialog<void>(
context: context,
future: myFutureFunction,
dialogBuilder: (context, _) => AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('Custom message'),
],
),
),
);
Using SimpleLoadingDialogTheme
(recommended)
To customize the appearance of the dialog using the SimpleLoadingDialogTheme
extension, define a theme in your app and pass it to the showSimpleLoadingDialog
function:
MaterialApp(
title: 'My App',
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: Colors.blue,
extensions: [
SimpleLoadingDialogTheme(
dialogBuilder: (context, message) {
return AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(height: 16),
const CircularProgressIndicator(),
const SizedBox(height: 16),
Text(message),
const SizedBox(height: 16),
],
),
);
},
),
],
),
home: MyHomePage(),
);
final result = await showSimpleLoadingDialog<String>(
context: context,
future: myFutureFunction,
message: "Saving...",
);
Handling errors
If an error occurs while waiting for the Future
to complete, the exception will be rethrown. To handle the error, use a try-catch
block:
try {
await showSimpleLoadingDialog<void>(
context: context,
future: myFutureFunction,
);
} catch (e) {
// Handle the error.
}
Optional: Using a wrapper function to return a Result
type
You can define a wrapper function to show a loading dialog and return a Result
type.
Step 1: Define the Result
class
sealed class Result<T> {
const Result();
}
class Success<T> extends Result<T> {
const Success({required this.value});
final T value;
}
class Failure<T> extends Result<T> {
const Failure({required this.error, this.stackTrace});
final Object error;
final StackTrace? stackTrace;
}
Step 2: Create the wrapper function
Future<Result<T>> showSimpleLoadingDialogWithResult<T>({
required BuildContext context,
required Future<T> Function() future,
DialogBuilder? dialogBuilder,
String message = 'Loading...',
bool barrierDismissible = false,
}) async {
try {
final res = await showSimpleLoadingDialog(
context: context,
future: future,
dialogBuilder: dialogBuilder,
message: message,
barrierDismissible: barrierDismissible,
);
return Success(value: res);
} catch (err, stack) {
return Failure(error: err, stackTrace: stack);
}
}
Step 3: Show the dialog and handle the result
ElevatedButton(
onPressed: () async {
final result = await showSimpleLoadingDialogWithResult<String>(
context: context,
future: () async {
await Future<void>.delayed(const Duration(seconds: 1));
// return 'Hello';
throw Exception('Error');
},
);
if (context.mounted) {
switch (result) {
case Success():
context.showMessageSnackBar('Success result: ${result.value}');
case Failure():
context.showMessageSnackBar('Failed result: ${result.error}');
}
}
},
child: const Text('Optional: Show loading dialog with result'),
);
License
This package is licensed under the MIT License. See the LICENSE file for details.