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后再关闭加载框是没有问题的。

相关推荐
m0_738185827 小时前
Flutter 鸿蒙化实战:flutter_app_minimizer_plus 适配 OpenHarmony,一键最小化应用
flutter·华为·harmonyos·鸿蒙
动物园猫8 小时前
Flutter 鸿蒙实战:用 webview_flutter 三方库在 鸿蒙 中内嵌真实网页
flutter·华为·harmonyos
m0_7381858210 小时前
Flutter 鸿蒙化实战:flutter_app_badger 适配 OpenHarmony,应用角标
flutter·华为·harmonyos·鸿蒙
yuezhilangniao10 小时前
FVM 与 Flutter 环境配置完全指南:从安装到日常使用
flutter
gnip13 小时前
Flutter GetX 三件套开发规范(Skill)
前端·flutter
m0_7381858214 小时前
Flutter 鸿蒙化实战:flutter_blue_plus 适配 OpenHarmony,蓝牙扫描连接开箱即用
flutter·华为·harmonyos·鸿蒙
传奇开心果编程15 小时前
【Flutter入门练中学】第3课:滚动与列表
android·学习·flutter·ui·ios
勤劳打代码15 小时前
从 Demo 搭建的Flutter 演示项目 —— Forge
flutter·客户端·vibecoding
m0_7381858215 小时前
Flutter 鸿蒙化实战:flutter_background_service 适配 OpenHarmony,后台服务
flutter·华为·harmonyos·鸿蒙
事圆则缓16 小时前
Flutter 状态管理框架对比(一):先看地图,再选工具
前端·javascript·flutter