Flutter覆盖层管理插件overlay_kit的使用

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

Flutter覆盖层管理插件overlay_kit的使用

overlay_kit 是一个用于管理Flutter应用中覆盖层(Overlay)的插件,提供了加载进度、Toast消息等功能。以下是关于如何使用该插件的详细说明和完整示例代码。

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 overlay_kit 依赖:

dependencies:
  overlay_kit: ^1.0.7

2. 导入包

在 Dart 文件中导入 overlay_kit 包:

import 'package:overlay_kit/overlay_kit.dart';

3. 使用 OverlayKit 包裹 MaterialApp

为了使 overlay_kit 在整个应用中生效,需要将 MaterialApp 包裹在 OverlayKit 中:

[@override](/user/override)
Widget build(BuildContext context) {
  return OverlayKit(
    child: MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    ),
  );
}

4. 功能介绍

1. 加载进度 (Loading Progress)

overlay_kit 提供了简单的 API 来显示和隐藏加载进度。

  • 启动加载进度

    OverlayLoadingProgress.start();
    
  • 停止加载进度

    OverlayLoadingProgress.stop();
    
  • 完整示例

    OverlayLoadingProgress.start();
    await Future.delayed(const Duration(seconds: 3));
    OverlayLoadingProgress.stop();
    
    loading progress
  • 使用 GIF 图片

    OverlayLoadingProgress.start(gifOrImagePath: 'assets/loading.gif');
    await Future.delayed(const Duration(seconds: 3));
    OverlayLoadingProgress.stop();
    
    gif loading progress
  • 使用自定义 Widget

    OverlayLoadingProgress.start(
      widget: Container(
        width: MediaQuery.of(context).size.width / 4,
        padding: EdgeInsets.all(MediaQuery.of(context).size.width / 13),
        child: const AspectRatio(
          aspectRatio: 1,
          child: CircularProgressIndicator(),
        ),
      ),
    );
    await Future.delayed(const Duration(seconds: 3));
    OverlayLoadingProgress.stop();
    
2. Toast 消息 (Toast Message)

overlay_kit 还提供了显示 Toast 消息的功能。

  • 显示 Toast 消息

    OverlayToastMessage.show(textMessage: 'Dismiss All And Show Toast');
    
    toast message
  • 使用自定义 Widget

    OverlayToastMessage.show(
      widget: yourWidget,
    );
    
    custom toast
3. Future 扩展 (Future Extension)

overlay_kit 提供了一个扩展方法 callWithProgress(),可以在执行异步操作时自动显示加载进度。

Future.delayed(const Duration(seconds: 5)).callWithProgress();

5. 完整示例代码

以下是一个完整的示例代码,展示了如何使用 overlay_kit 的各种功能:

import 'dart:async';
import 'dart:math';

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

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return OverlayKit(
      appPrimaryColor: Colors.red, // 设置全局主题颜色
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(primaryColor: Colors.black),
        home: const MyHomePage(
          title: 'Flutter Demo Home Page',
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color.fromRGBO(Random().nextInt(250), Random().nextInt(250), Random().nextInt(250), 1),
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: onTapStartBtn,
              child: const Text('Start Loading Progress'),
            ),
            ElevatedButton(
              onPressed: onTapStartGifLoadingProgressBtn,
              child: const Text('Start Gif Loading Progress'),
            ),
            ElevatedButton(
              onPressed: onTapStartCustomLoadingProgressBtn,
              child: const Text('Start Custom Loading Progress'),
            ),
            ElevatedButton(
              onPressed: onTapStartWithExtensionBtn,
              child: const Text('Start Loading Progress With Extension'),
            ),
            ElevatedButton(
              onPressed: onTapCustomBtn,
              child: const Text('Show Custom Toast'),
            ),
            ElevatedButton(
              onPressed: onTapShowToastBtn,
              child: const Text('Show Toast'),
            ),
            ElevatedButton(
              onPressed: onTapDismissAllAndShowToastBtn,
              child: const Text('Dismiss All And Show Toast'),
            ),
            ElevatedButton(
              onPressed: onTapShowToastWithButtonBtn,
              child: const Text('Show Toast With Button'),
            ),
            ElevatedButton(
              onPressed: onTapNewPageBtn,
              child: const Text('New Page'),
            ),
          ],
        ),
      ),
    );
  }

  // 启动默认加载进度
  void onTapStartBtn() async {
    OverlayLoadingProgress.start();
    await Future.delayed(const Duration(seconds: 10));
    OverlayLoadingProgress.stop();
  }

  // 使用扩展方法启动加载进度
  void onTapStartWithExtensionBtn() async {
    Future.delayed(const Duration(seconds: 5)).callWithProgress();
  }

  // 启动 GIF 加载进度
  void onTapStartGifLoadingProgressBtn() async {
    OverlayLoadingProgress.start(
      gifOrImagePath: 'assets/loading.gif', // 确保 assets 文件夹中有 loading.gif
      loadingWidth: 50,
    );
    await Future.delayed(const Duration(seconds: 3));
    OverlayLoadingProgress.stop();
  }

  // 启动自定义加载进度
  void onTapStartCustomLoadingProgressBtn() async {
    OverlayLoadingProgress.start(
      widget: Container(
        height: 100,
        width: 100,
        color: Colors.black38,
        child: const Center(
          child: CircularProgressIndicator(
            color: Colors.green,
          ),
        ),
      ),
    );
    await Future.delayed(const Duration(seconds: 8));
    OverlayLoadingProgress.stop();
  }

  // 显示普通 Toast 消息
  void onTapShowToastBtn() {
    OverlayToastMessage.show(
      ignoring: false,
      textMessage: 'Toast Message',
    );
  }

  // 关闭所有 Toast 并显示新的 Toast 消息
  void onTapDismissAllAndShowToastBtn() {
    OverlayToastMessage.show(
      dismissAll: true,
      textMessage: 'Dismiss All And Show Toast Message',
    );
  }

  // 显示自定义 Toast
  void onTapCustomBtn() {
    OverlayToastMessage.show(
      widget: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 15),
        child: Container(
          decoration: BoxDecoration(
            boxShadow: const [
              BoxShadow(
                spreadRadius: 3,
                blurRadius: 10,
                offset: Offset(0, 5),
                color: Colors.black12,
              )
            ],
            borderRadius: BorderRadius.circular(15),
            color: Colors.white,
          ),
          child: const Padding(
            padding: EdgeInsets.all(15),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Icon(Icons.ac_unit),
                SizedBox(width: 15),
                Expanded(
                  child: Text(
                    'Custom Toast',
                    style: TextStyle(fontWeight: FontWeight.w500, fontSize: 18),
                    textAlign: TextAlign.start,
                    maxLines: 2,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  // 跳转到新页面
  void onTapNewPageBtn() {
    Navigator.of(context).push(MaterialPageRoute(
      builder: (_) => const MyHomePage(
        title: '',
      ),
    ));
  }

  // 显示带有按钮的 Toast
  void onTapShowToastWithButtonBtn() {
    OverlayToastMessage.show(
      ignoring: false,
      duration: const Duration(seconds: 5),
      widget: const _ToastWithButtonWidget(
        textMessage: 'Toast Message',
        backgroundColor: Colors.white,
        primaryColor: Colors.purple,
        duration: 5,
      ),
    );
  }
}

// 自定义 Toast 组件
class _ToastWithButtonWidget extends StatefulWidget {
  final String textMessage;
  final Color backgroundColor;
  final Color primaryColor;
  final int duration;

  const _ToastWithButtonWidget({
    required this.textMessage,
    required this.backgroundColor,
    required this.primaryColor,
    required this.duration,
  });

  [@override](/user/override)
  State<_ToastWithButtonWidget> createState() => _ToastWithButtonWidgetState();
}

class _ToastWithButtonWidgetState extends State<_ToastWithButtonWidget> {
  double progress = 0;
  Timer? timer;

  [@override](/user/override)
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final durationInMillisecond = widget.duration * 1000;
      timer = Timer.periodic(const Duration(milliseconds: 1), (time) {
        progress = (timer!.tick + 200) / durationInMillisecond;
        setState(() {});
      });
    });
  }

  [@override](/user/override)
  void dispose() {
    timer?.cancel();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(12),
      child: Card(
        color: widget.backgroundColor,
        shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 6),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  const SizedBox(width: 16),
                  Expanded(
                    child: Text(
                      widget.textMessage,
                      maxLines: 2,
                      overflow: TextOverflow.ellipsis,
                    ),
                  ),
                  const SizedBox(width: 8),
                  SizedBox(
                    height: 40,
                    width: 4,
                    child: DecoratedBox(
                      decoration: BoxDecoration(
                        color: Colors.grey,
                        borderRadius: BorderRadius.circular(4),
                      ),
                    ),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      overlayColor: Colors.grey,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(4),
                      ),
                    ),
                    child: const Text(
                      'Ekle',
                      style: TextStyle(
                        color: Colors.black,
                        fontWeight: FontWeight.w400,
                        fontSize: 16,
                      ),
                    ),
                    onPressed: () {
                      debugPrint('Button Taped');
                    },
                  ),
                  const SizedBox(width: 8),
                ],
              ),
            ),
            ColoredBox(
              color: Colors.red,
              child: LinearProgressIndicator(
                value: progress,
                minHeight: 3,
                valueColor: AlwaysStoppedAnimation<Color?>(
                  widget.primaryColor,
                ),
                color: widget.primaryColor,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何使用 overlay_kit 插件在 Flutter 中管理覆盖层的代码示例。overlay_kit 是一个用于在 Flutter 应用中轻松管理覆盖层的插件。它提供了一个简单的方式来显示和隐藏覆盖层,而无需手动操作 OverlayOverlayEntry

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

dependencies:
  flutter:
    sdk: flutter
  overlay_kit: ^最新版本号 # 请替换为实际的最新版本号

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

以下是一个简单的示例,展示如何使用 overlay_kit 来显示和隐藏一个覆盖层:

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

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

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

class OverlayKitExample extends StatefulWidget {
  @override
  _OverlayKitExampleState createState() => _OverlayKitExampleState();
}

class _OverlayKitExampleState extends State<OverlayKitExample> {
  final OverlayKit _overlayKit = OverlayKit();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OverlayKit Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            _showOverlay();
          },
          child: Text('Show Overlay'),
        ),
      ),
    );
  }

  void _showOverlay() {
    _overlayKit.show(
      context: context,
      builder: (context) => Material(
        elevation: 8.0,
        child: Container(
          height: 200,
          width: 200,
          color: Colors.white,
          child: Center(
            child: ElevatedButton(
              onPressed: () {
                _overlayKit.hide();
              },
              child: Text('Hide Overlay'),
            ),
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _overlayKit.dispose();
    super.dispose();
  }
}

在这个示例中:

  1. 我们创建了一个 OverlayKit 实例,并在 State 中持有它。
  2. Scaffoldbody 中,我们放置了一个 ElevatedButton,点击该按钮将显示覆盖层。
  3. _showOverlay 方法使用 _overlayKit.show 来显示一个覆盖层。覆盖层包含了一个 Container,其中有一个按钮用于隐藏覆盖层。
  4. dispose 方法中,我们调用 _overlayKit.dispose 来清理资源。

这个示例展示了如何使用 overlay_kit 插件来管理覆盖层。你可以根据需要自定义覆盖层的内容和样式。希望这个示例对你有所帮助!

回到顶部