0
点赞
收藏
分享

微信扫一扫

报错 - decord 在 macOS Silicon 安装失败

以沫的窝 01-12 18:00 阅读 43
flutter

背景:
在使用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避免重复显示的实现
2. 创建一个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后再关闭加载框是没有问题的。

举报

相关推荐

0 条评论