Flutter加载对话框插件simple_loading_dialog的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter加载对话框插件 simple_loading_dialog 的使用

simple_loading_dialog 是一个简单的全屏加载对话框插件,适用于Flutter应用。它在等待一个Future完成时显示一个全屏的进度对话框,并且可以自定义对话框的外观。

特性

  • 简单的全屏加载对话框。
  • 在等待Future完成时阻止用户输入。
  • 发生错误时重新抛出异常。
  • 可自定义对话框的外观。
  • 返回Future的结果。

安装

要在项目中使用该插件,请在pubspec.yaml文件中添加依赖:

dependencies:
  simple_loading_dialog: ^latest_version

然后运行flutter pub get来安装依赖。

使用示例

显示对话框

使用showSimpleLoadingDialog函数来显示对话框:

final result = await showSimpleLoadingDialog<String>(
  context: context,
  future: myFutureFunction,
);

这将在等待myFutureFunction完成时显示一个全屏的进度对话框。一旦Future完成,结果将被返回,对话框也会被关闭。

自定义外观

可以通过传递dialogBuilder来自定义对话框的外观:

await showSimpleLoadingDialog<void>(
  context: context,
  future: myFutureFunction,
  dialogBuilder: (context, _) => AlertDialog(
    content: Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        CircularProgressIndicator(),
        SizedBox(height: 16),
        Text('Custom message'),
      ],
    ),
  ),
);

使用SimpleLoadingDialogTheme(推荐)

通过在应用的主题中定义并传递SimpleLoadingDialogTheme来定制对话框的外观:

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...",
);

错误处理

如果在等待Future完成时发生错误,异常会被重新抛出。可以使用try-catch块来处理错误:

try {
  await showSimpleLoadingDialog<void>(
    context: context,
    future: myFutureFunction,
  );
} catch (e) {
  // Handle the error.
}

可选:使用包装函数返回Result类型

可以定义一个包装函数来显示加载对话框并返回一个Result类型。

第一步:定义Result

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

第二步:创建包装函数

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

第三步:显示对话框并处理结果

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'),
);

完整示例代码

以下是一个完整的示例,展示了如何使用simple_loading_dialog插件:

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Simple Loading Dialog Demo',
      theme: ThemeData(
        useMaterial3: true,
        colorSchemeSeed: Colors.blue,
      ),
      home: const DemoPage(),
    );
  }
}

class DemoPage extends StatelessWidget {
  const DemoPage({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Simple Loading Dialog Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            ElevatedButton(
              onPressed: () async {
                final result = await showSimpleLoadingDialog<String>(
                  context: context,
                  future: () async {
                    await Future<void>.delayed(const Duration(seconds: 1));
                    return 'Hello';
                  },
                );

                if (context.mounted) {
                  context.showMessageSnackBar('Success result: $result');
                }
              },
              child: const Text('Show loading dialog'),
            ),
            const SizedBox(height: 32),
            ElevatedButton(
              onPressed: () async {
                try {
                  final result = await showSimpleLoadingDialog<String>(
                    context: context,
                    future: () async {
                      await Future<void>.delayed(const Duration(seconds: 1));
                      throw Exception('Error');
                    },
                  );

                  if (context.mounted) {
                    context.showMessageSnackBar('Success result: $result');
                  }
                } catch (e) {
                  if (context.mounted) {
                    context.showMessageSnackBar('Failed result: $e');
                  }
                }
              },
              child: const Text('Show loading dialog with error'),
            ),
            const SizedBox(height: 32),
            ElevatedButton(
              onPressed: () async {
                final result = await showSimpleLoadingDialog<String>(
                  context: context,
                  future: () async {
                    await Future<void>.delayed(const Duration(seconds: 1));
                    return 'World';
                  },
                  dialogBuilder: (context, _) {
                    return const AlertDialog(
                      content: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          SizedBox(height: 16),
                          CircularProgressIndicator(),
                          SizedBox(height: 16),
                          Text('Loading...'),
                          SizedBox(height: 16),
                        ],
                      ),
                    );
                  },
                );

                if (context.mounted) {
                  context.showMessageSnackBar('Success result: $result');
                }
              },
              child: const Text('Show loading dialog with custom dialog'),
            ),
            const SizedBox(height: 32),
            ElevatedButton(
              onPressed: () async {
                final result = await showSimpleLoadingDialogWithResult<String>(
                  context: context,
                  future: () async {
                    await Future<void>.delayed(const Duration(seconds: 1));
                    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'),
            ),
          ],
        ),
      ),
    );
  }
}

extension BuildContextX on BuildContext {
  void showMessageSnackBar(String message) {
    ScaffoldMessenger.of(this).showSnackBar(
      SnackBar(
        content: Text(message),
        duration: const Duration(milliseconds: 500),
      ),
    );
  }
}

更多关于Flutter加载对话框插件simple_loading_dialog的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter加载对话框插件simple_loading_dialog的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用simple_loading_dialog插件的示例代码。这个插件可以帮助你在应用中显示加载对话框。

首先,你需要在你的pubspec.yaml文件中添加simple_loading_dialog依赖:

dependencies:
  flutter:
    sdk: flutter
  simple_loading_dialog: ^2.0.0  # 请确保使用最新版本

然后运行flutter pub get来获取依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用simple_loading_dialog

示例代码

  1. 导入必要的包

在你的Dart文件中(比如main.dart),导入simple_loading_dialog包:

import 'package:flutter/material.dart';
import 'package:simple_loading_dialog/simple_loading_dialog.dart';
  1. 创建加载对话框实例

在你的主应用程序类中,创建一个SimpleLoadingDialog实例:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final SimpleLoadingDialog _loadingDialog = SimpleLoadingDialog();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Simple Loading Dialog Example'),
        ),
        body: MyHomePage(_loadingDialog),
      ),
    );
  }
}
  1. 在页面中显示加载对话框

创建一个MyHomePage类,并在这个类中显示加载对话框:

class MyHomePage extends StatefulWidget {
  final SimpleLoadingDialog loadingDialog;

  MyHomePage(this.loadingDialog);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        onPressed: () async {
          // 显示加载对话框
          widget.loadingDialog.show(context);

          // 模拟长时间操作
          await Future.delayed(Duration(seconds: 3));

          // 关闭加载对话框
          widget.loadingDialog.hide();
        },
        child: Text('Show Loading Dialog'),
      ),
    );
  }
}

在这个示例中,当用户点击按钮时,会显示一个加载对话框,并在3秒后自动关闭。

自定义加载对话框

你还可以自定义加载对话框的样式。例如,你可以设置对话框的消息、背景颜色、指示器类型等:

SimpleLoadingDialog(
  message: 'Please wait...',
  progressIndicator: CircularProgressIndicator(
    valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
  ),
  backgroundColor: Colors.white.withOpacity(0.8),
  animationType: DialogTransitionAnimation.SCALE,
  isDismissible: false,
);

然后,在MyApp类中使用这个自定义的加载对话框实例:

final SimpleLoadingDialog _loadingDialog = SimpleLoadingDialog(
  message: 'Please wait...',
  progressIndicator: CircularProgressIndicator(
    valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
  ),
  backgroundColor: Colors.white.withOpacity(0.8),
  animationType: DialogTransitionAnimation.SCALE,
  isDismissible: false,
);

这样,你就能够在Flutter应用中灵活地使用simple_loading_dialog插件来显示加载对话框了。希望这个示例对你有帮助!

回到顶部