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

相关推荐
2501_944521593 小时前
Ramda 跨端三方库仓颉适配全流程
开发语言·javascript·flutter·php
大龄秃头程序员9 小时前
Flutter 架构里总被混淆的 IoC、DI、Service Locator,到底是什么关系?
flutter
事圆则缓14 小时前
Flutter 与原生交互的最后一层:RTC 视频帧怎么走
flutter·音视频·实时音视频
2601_9498477515 小时前
jose 跨端三方库仓颉适配全流程
前端·javascript·flutter
2601_9499706917 小时前
msgpackr 跨端三方库仓颉适配全流程
前端·javascript·flutter
2601_949970691 天前
HumanizeDuration 跨端三方库仓颉适配全流程
前端·javascript·flutter
传奇开心果编程1 天前
【Flutter踩坑排雷】第3课:const 误用坑|const 错误使用引发 UI 异常与性能损耗
flutter·移动开发·跨平台·dart·编程语言理论·编程框架·声明式ui
程序员老刘1 天前
你的Flutter项目要不要紧急升级3.47.8?
flutter·客户端
Talyra421 天前
不想开会员,我写了一个记账 App
flutter
2601_949575862 天前
JSON5 跨端三方库仓颉适配全流程
前端·javascript·flutter