Flutter加载覆盖层插件loader_overlay的使用

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

Flutter加载覆盖层插件loader_overlay的使用

loader_overlay 是一个用于Flutter应用的插件,它允许开发者在执行异步操作时显示一个加载遮罩层(overlay),以防止用户在此期间与屏幕交互。这个插件非常适合用来提升用户体验,尤其是在网络请求或复杂计算正在进行的时候。下面将详细介绍如何使用 loader_overlay 插件,并提供完整的示例代码。

一、基本用法

1. 引入依赖

首先,在你的 pubspec.yaml 文件中添加 loader_overlay 作为依赖:

dependencies:
  flutter:
    sdk: flutter
  loader_overlay: ^3.0.0 # 确保使用最新版本

然后运行 flutter pub get 来安装插件。

2. 使用LoaderOverlay包裹页面

接下来,在需要展示加载遮罩的地方使用 LoaderOverlay 包裹住整个页面。例如:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LoaderOverlay(
        child: MyHomePage(title: 'Flutter Demo Home Page'),
      ),
    );
  }
}

此时,你已经配置好了加载遮罩功能,但还没有实际显示出来。

3. 显示和隐藏加载遮罩

要显示加载遮罩,只需调用:

context.loaderOverlay.show();

这会显示默认的圆形进度指示器。如果你想隐藏它,可以调用:

context.loaderOverlay.hide();

此外,还可以通过以下方式检查遮罩是否可见:

final isVisible = context.loaderOverlay.visible;

注意:每次显示或隐藏遮罩都需要有有效的 BuildContext

二、导航中的全局使用

如果你希望在整个应用程序中都能使用加载遮罩,而不仅仅是在某个特定页面上,那么可以考虑使用 GlobalLoaderOverlay。它的工作原理类似于 LoaderOverlay,只不过它是作用于所有路由上的。

return GlobalLoaderOverlay(
  child: MaterialApp(
    debugShowCheckedModeBanner: false,
    title: 'Flutter Demo',
    theme: ThemeData(primarySwatch: Colors.teal, fontFamily: 'Baloo'),
    initialRoute: '/',
    routes: {
      '/': (context) => Page1(),
      '/page2': (context) => Page2(),
    },
  ),
);

三、自定义加载遮罩样式

除了默认的圆形进度条外,你还可以根据需求自定义加载遮罩的外观。比如,你可以引入 flutter_spinkit 这样的动画库来创建更有趣的加载效果。

LoaderOverlay(
  useDefaultLoading: false,
  overlayWidgetBuilder: (_) { 
    return Center(
      child: SpinKitCubeGrid(
        color: Colors.red,
        size: 50.0,
      ),
    );
  },
  child: MyHomePage(title: 'Flutter Demo Home Page'),
),

同时,也可以调整遮罩的颜色和透明度:

overlayColor: Colors.yellow.withOpacity(0.8),

四、带有进度信息的加载遮罩

有时候我们可能想要向用户传达当前任务的具体进展情况。这时可以通过传递 progress 参数给 show() 方法,并在 overlayWidgetBuilder 中处理这些信息。

context.loaderOverlay.show(
  progress: 'Doing progress #0',
);

await Future.delayed(Duration(seconds: 1));
context.loaderOverlay.progress('Doing progress #1');
// ...

五、完整示例

最后,这里给出一个包含上述所有特性的完整例子:

import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:loader_overlay/loader_overlay.dart';

void main() => runApp(const MyAppGlobalLoaderOverlay());

class MyAppGlobalLoaderOverlay extends StatelessWidget {
  const MyAppGlobalLoaderOverlay({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GlobalLoaderOverlay(
      duration: const Duration(milliseconds: 250),
      reverseDuration: const Duration(milliseconds: 250),
      overlayColor: Colors.grey.withAlpha(204), // 设置为半透明灰色
      overlayWidgetBuilder: (_) {
        return const Center(
          child: SpinKitCubeGrid(
            color: Colors.red,
            size: 50.0,
          ),
        );
      },
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Demo',
        theme: ThemeData(
          primaryColor: Colors.black,
          fontFamily: 'Baloo',
        ),
        initialRoute: '/',
        routes: {
          '/': (context) => const MyHomePage(),
        },
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _isLoaderVisible = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () async {
                context.loaderOverlay.show();
                setState(() {
                  _isLoaderVisible = context.loaderOverlay.visible;
                });
                await Future.delayed(const Duration(seconds: 2));
                if (_isLoaderVisible && context.mounted) {
                  context.loaderOverlay.hide();
                }
                setState(() {
                  _isLoaderVisible = context.loaderOverlay.visible;
                });
              },
              child: const Text('Show overlay for 2 seconds'),
            ),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: () async {
                context.loaderOverlay.show(
                    widgetBuilder: (progress) {
                      return ReconnectingOverlay(
                        progress != null ? progress as String : null,
                      );
                    },
                    progress: 'Trying to reconnect');
                setState(() {
                  _isLoaderVisible = context.loaderOverlay.visible;
                });
                await Future.delayed(const Duration(seconds: 3));
                if (_isLoaderVisible && context.mounted) {
                  context.loaderOverlay.hide();
                }
                setState(() {
                  _isLoaderVisible = context.loaderOverlay.visible;
                });
              },
              child: const Text('Show custom loader overlay for 3 seconds'),
            ),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: () async {
                context.loaderOverlay.show(
                  progress: 'Doing progress #0',
                );
                setState(() {
                  _isLoaderVisible = context.loaderOverlay.visible;
                });

                await Future.delayed(const Duration(seconds: 1));
                if (context.mounted) {
                  context.loaderOverlay.progress('Doing progress #1');
                }
                await Future.delayed(const Duration(seconds: 1));
                if (context.mounted) {
                  context.loaderOverlay.progress('Doing progress #2');
                }
                await Future.delayed(const Duration(seconds: 1));
                if (context.mounted) {
                  context.loaderOverlay.progress('Doing progress #3');
                }
                await Future.delayed(const Duration(seconds: 1));

                if (_isLoaderVisible && context.mounted) {
                  context.loaderOverlay.hide();
                }
                setState(() {
                  _isLoaderVisible = context.loaderOverlay.visible;
                });
              },
              child:
                  const Text('Show loader overlay for 5 seconds with progress'),
            ),
            const SizedBox(height: 34),
            Text('Is loader visible: $_isLoaderVisible'),
          ],
        ),
      ),
    );
  }
}

class ReconnectingOverlay extends StatelessWidget {
  final String? progress;

  const ReconnectingOverlay(this.progress, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) => Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const CircularProgressIndicator(),
            const SizedBox(height: 12),
            const Text(
              'Reconnecting...',
            ),
            const SizedBox(height: 12),
            Text(
              progress ?? '',
            ),
          ],
        ),
      );
}

以上就是关于 loader_overlay 插件的基本介绍及其使用方法。通过合理运用该插件,可以使我们的应用程序更加友好且专业。如果有任何问题或者建议,请参考官方文档或前往GitHub仓库提交issue。


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

1 回复

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


当然,下面是一个关于如何在Flutter中使用loader_overlay插件的示例代码。这个插件通常用于在应用执行某些耗时操作时显示一个加载覆盖层,以提高用户体验。

首先,确保你已经在pubspec.yaml文件中添加了loader_overlay依赖:

dependencies:
  flutter:
    sdk: flutter
  loader_overlay: ^x.y.z  # 请替换为最新版本号

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

接下来,你可以在你的Flutter应用中这样使用loader_overlay

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LoaderOverlayExample(),
    );
  }
}

class LoaderOverlayExample extends StatefulWidget {
  @override
  _LoaderOverlayExampleState createState() => _LoaderOverlayExampleState();
}

class _LoaderOverlayExampleState extends State<LoaderOverlayExample> with LoaderOverlayMixin {
  bool isLoading = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Loader Overlay Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Tap the button to show the loader overlay'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                setState(() {
                  isLoading = true;
                });

                // Simulate a time-consuming task
                await Future.delayed(Duration(seconds: 3));

                setState(() {
                  isLoading = false;
                });
              },
              child: Text('Show Loader'),
            ),
          ],
        ),
      ),
      // Add the LoaderOverlay widget here
      loaderOverlay: LoaderOverlay(
        isActive: isLoading,
        color: Colors.black.withOpacity(0.5),
        child: Center(
          child: CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
          ),
        ),
      ),
    );
  }
}

代码说明:

  1. 依赖导入

    • import 'package:loader_overlay/loader_overlay.dart';:导入loader_overlay包。
  2. 使用LoaderOverlayMixin

    • 通过with LoaderOverlayMixin在状态类中混合使用LoaderOverlayMixin,这允许你控制加载覆盖层的显示状态。
  3. 构建UI

    • 使用Scaffold构建应用的基本布局。
    • 添加一个按钮,当按钮被点击时,isLoading状态变为true,模拟一个耗时操作(通过Future.delayed),然后isLoading状态变为false
  4. 加载覆盖层

    • ScaffoldloaderOverlay属性中添加LoaderOverlay
    • isActive属性绑定到isLoading状态,当isLoadingtrue时显示加载覆盖层。
    • 自定义加载覆盖层的颜色和子元素(例如,一个居中的CircularProgressIndicator)。

这样,当按钮被点击时,加载覆盖层会显示出来,并在模拟的耗时操作完成后隐藏。希望这个示例对你有帮助!

回到顶部