Flutter中Get.snackbar和Get.dialog关闭冲突问题记录

背景:

在使用GetX框架时,同时使用了Get.snackbar提示框和Get.dialog加载框,当这两个widget同时存在时,Get.dialog加载框调用Get.back()无法正常关闭。

冲突解释:

之所以会产生冲突,是因为Get.snackbar在关闭时会有一个动画,这个动画的默认持续时间为1s,这个动画的持续时间内,Get.snackbar并没有真正意义上的关闭,这时候我们调用Get.back()是无法关闭Get.dialog。

实现:

  1. 创建一个统一的SnackBarManager去管理提示框。

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

    class SnackBarManager {
    factory SnackBarManager() => instance;

    static final SnackBarManager instance = SnackBarManager._internal();

    SnackBarManager._internal();

    String _lastMessage = '';

    int _lastDuration = 0;

    int _lastTime = 0;

    void showSnackBar(String title, String message, {Color? backgroundColor, Duration? duration}) {
    var currentTime = DateTime.now().millisecondsSinceEpoch;
    // 相同消息持续时间内重复提交时,返回
    if (currentTime - _lastTime < _lastDuration * 1000 && _lastMessage == message) {
    return;
    }

    复制代码
     dismissSnackBar();
    
     Get.snackbar(
       title,
       message,
       backgroundColor: backgroundColor ?? Colors.black12,
       duration: duration ?? Duration(seconds: 2), // 提示框持续时间
       animationDuration: Duration(milliseconds: 0), // 过渡动画的时间,这里设置为0是为了在使用Get.dialog时避免关闭冲突
     );
    
     _lastDuration = duration?.inSeconds ?? 2;
     _lastTime = DateTime.now().millisecondsSinceEpoch;
     _lastMessage = message;

    }

    void dismissSnackBar() {
    Get.closeCurrentSnackbar();
    }
    }

这是一个避免重复显示的显示的提示框,可参考博客:Flutter中Get.snackbar避免重复显示的实现

  1. 创建一个LoadingDialog去实现加载框。

    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    import 'package:get/get_core/src/get_main.dart';

    class LoadingDialog {
    static void show([String? msg]) {
    Get.dialog(
    PopScope(
    canPop: false,
    child: Center(
    child: Container(
    padding: EdgeInsets.symmetric(horizontal: 24, vertical: 16), // 减小内边距
    decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.circular(8),
    ),
    child: Row(
    mainAxisSize: MainAxisSize.min, // 设置为最小宽度
    children: [
    SizedBox(
    width: 24, // 减小加载图标尺寸
    height: 24,
    child: CircularProgressIndicator(
    strokeWidth: 2.0, // 可以适当减小进度条宽度
    ),
    ),
    SizedBox(width: 12), // 减小间距
    Text(
    msg ?? "加载中...",
    style: TextStyle(fontSize: 14, color: Colors.black), // 可以适当调整字体大小
    ),
    ],
    ),
    ),
    ),
    ),
    barrierDismissible: false,
    );
    }

    static void hide() {
    if (Get.isDialogOpen ?? false) {
    // 先关闭 Snackbar
    Get.closeCurrentSnackbar();
    // 添加延迟以确保 Snackbar 已关闭
    Future.delayed(Duration(milliseconds: 100), () {
    if (Get.isDialogOpen ?? false) {
    Get.back();
    }
    });
    }
    }
    }

在关闭加载框之前,会先关闭提示框,由于Get.snackbar动画时长已经设置为0,此时延迟100ms后再关闭加载框是没有问题的。

相关推荐
liulian091621 小时前
Flutter 跨平台路由与状态管理:go_router 与 Riverpod 的 OpenHarmony总结
flutter·华为·学习方法·harmonyos
liulian09161 天前
Flutter for OpenHarmony 跨平台技术实战:flutter_animate 与 pull_to_refresh 库的鸿蒙化适配总结
flutter·华为·学习方法·harmonyos
IntMainJhy1 天前
【flutter for open harmony】第三方库 Flutter 二维码生成的鸿蒙化适配与实战指南
数据库·flutter·华为·sqlite·harmonyos
jiejiejiejie_1 天前
Flutter for OpenHarmony 底部选项卡与多语言适配小记:让 App 更贴心的两次小升级✨
flutter·华为·harmonyos
jiejiejiejie_1 天前
Flutter for OpenHarmony 应用更新检测与萌系搜索功能实战小记✨
flutter·华为·harmonyos
IntMainJhy1 天前
Flutter 三方库 Firebase Messaging 鸿蒙化适配与实战指南(权限检查+设备Token获取全覆盖)
flutter·华为·harmonyos
liulian09161 天前
Flutter 依赖注入与设备信息库:get_it 与 device_info_plus 的 OpenHarmony 适配指南总结
flutter·华为·学习方法·harmonyos
里欧跑得慢1 天前
微交互设计模式:提升用户体验的细节之美
前端·css·flutter·web
stringwu1 天前
Flutter GetX 核心坑及架构选型与可替换性方案
前端·flutter
IntMainJhy1 天前
【flutter for open harmony】第三方库Flutter 国际化多语言的鸿蒙化适配与实战指南
数据库·flutter·华为·sqlite·harmonyos