Browse Source

Update 优化toast,统一使用SnackBar,移除fluttertoast插件

Yue 1 day ago
parent
commit
ccae7804e9
1 changed files with 99 additions and 63 deletions
  1. 99 63
      UI/CF.APP/chicken_farm/lib/core/utils/toast.dart

+ 99 - 63
UI/CF.APP/chicken_farm/lib/core/utils/toast.dart

@@ -1,46 +1,111 @@
 import 'package:chicken_farm/core/services/navigation_service.dart';
 import 'package:flutter/material.dart';
-import 'package:fluttertoast/fluttertoast.dart';
 
 class ToastUtil {
-  // 用于跟踪最近显示的Toast消息
-  static final Set<String> _recentMessages = {};
-  static const Duration _deduplicationDuration = Duration(seconds: 3);
+  static void success(String message) => show(message, bgColor: Colors.green);
+  static void successB(String message) =>
+      show(message, bgColor: Colors.green, position: "bottom");
 
-  static void success(
-    String message, [
-    Toast? toastLength = Toast.LENGTH_SHORT,
-    ToastGravity? gravity = ToastGravity.CENTER,
-    Color? textColor = Colors.white,
-    double? fontSize = 16.0,
-  ]) => show(message, Colors.green, toastLength, gravity, textColor, fontSize);
+  static void error(String message, [double duration = 3.0]) =>
+      show(message, duration: duration, bgColor: Colors.red);
+  static void errorB(String message, [double duration = 3.0]) => show(
+    message,
+    duration: duration,
+    bgColor: Colors.red,
+    position: "bottom",
+  );
 
-  static void error(
-    String message, [
-    Toast? toastLength = Toast.LENGTH_SHORT,
-    ToastGravity? gravity = ToastGravity.CENTER,
-    Color? textColor = Colors.white,
-    double? fontSize = 16.0,
-  ]) => show(message, Colors.red, toastLength, gravity, textColor, fontSize);
+  static void info(String message) => show(message, bgColor: Colors.lightBlue);
+  static void infoB(String message) =>
+      show(message, bgColor: Colors.lightBlue, position: "bottom");
 
-  static void info(
-    String message, [
-    Toast? toastLength = Toast.LENGTH_SHORT,
-    ToastGravity? gravity = ToastGravity.CENTER,
-    Color? textColor = Colors.white,
-    double? fontSize = 16.0,
-  ]) => show(message, Colors.blue, toastLength, gravity, textColor, fontSize);
+  static void warning(String message) => show(message, bgColor: Colors.orange);
+  static void warningB(String message) =>
+      show(message, bgColor: Colors.orange, position: "bottom");
 
-  static void warning(
-    String message, [
-    Toast? toastLength = Toast.LENGTH_SHORT,
-    ToastGravity? gravity = ToastGravity.CENTER,
+  static void show(
+    String message, {
+    Color? bgColor = Colors.lightBlue,
+    double duration = 2.0,
+    String position = "center",
     Color? textColor = Colors.white,
     double? fontSize = 16.0,
-  ]) => show(message, Colors.orange, toastLength, gravity, textColor, fontSize);
+  }) {
+    final BuildContext? context = NavigationService.navigatorKey.currentContext;
+    if (context == null) return;
+
+    // 确保在WidgetsBinding.instance调度器中执行
+    WidgetsBinding.instance.addPostFrameCallback((_) {
+      final scaffoldMessenger = ScaffoldMessenger.of(context);
+
+      // 先清除之前的snackbars
+      scaffoldMessenger.clearSnackBars();
+
+      // 计算显示时长
+      final Duration displayDuration = Duration(
+        milliseconds: (duration * 1000).toInt(),
+      );
+      bool isBottomPosition = position == "bottom";
+      bool isCenterPosition = !isBottomPosition;
+
+      // 显示新的snackbar
+      scaffoldMessenger.showSnackBar(
+        SnackBar(
+          content: Text(
+            message,
+            textAlign: isCenterPosition ? TextAlign.center : TextAlign.left,
+            style: TextStyle(color: textColor, fontSize: fontSize),
+          ),
+          backgroundColor: bgColor,
+          duration: displayDuration,
+          behavior: isCenterPosition
+              ? SnackBarBehavior.floating
+              : SnackBarBehavior.fixed,
+          shape: isCenterPosition
+              ? RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))
+              : null,
+          margin: isCenterPosition
+              ? _calculateCenterMargin(message, textColor, fontSize, context)
+              : null,
+          padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
+          showCloseIcon: duration == 0,
+        ),
+      );
+    });
+  }
+
+  /// 计算center位置的margin
+  static EdgeInsetsGeometry _calculateCenterMargin(
+    String message,
+    Color? textColor,
+    double? fontSize,
+    BuildContext context,
+  ) {
+    final textPainter = TextPainter(
+      text: TextSpan(
+        text: message,
+        style: TextStyle(color: textColor, fontSize: fontSize),
+      ),
+      textDirection: TextDirection.ltr,
+    )..layout();
+
+    final contentWidth = textPainter.width + 50; // 加上padding的宽度
+    final maxContentWidth = 320.0;
+    final actualWidth = contentWidth > maxContentWidth
+        ? maxContentWidth
+        : contentWidth;
+    final screenWidth = MediaQuery.of(context).size.width;
+    final horizontalMargin = (screenWidth - actualWidth) / 2;
+
+    return EdgeInsets.symmetric(
+      horizontal: horizontalMargin > 0 ? horizontalMargin : 20,
+      vertical: MediaQuery.of(context).size.height * 0.4,
+    );
+  }
 
   static Future<void> errorAlert(
     String message, {
+    VoidCallback? onConfirm,
     String? title,
     String confirmText = '确定',
     BuildContext? context,
@@ -51,7 +116,7 @@ class ToastUtil {
     if (dialogContext == null) {
       return;
     }
-    return await showDialog(
+    bool result = await showDialog(
       context: dialogContext,
       builder: (BuildContext context) {
         return AlertDialog(
@@ -114,6 +179,9 @@ class ToastUtil {
         );
       },
     );
+    if (result == true && onConfirm != null) {
+      onConfirm();
+    }
   }
 
   static Future<void> confirm(
@@ -231,36 +299,4 @@ class ToastUtil {
       onConfirm();
     }
   }
-
-  static void show(
-    String message, [
-    Color? backgroundColor = Colors.blue,
-    Toast? toastLength = Toast.LENGTH_SHORT,
-    ToastGravity? gravity = ToastGravity.CENTER,
-    Color? textColor = Colors.white,
-    double? fontSize = 16.0,
-  ]) {
-    // 检查消息是否在去重期内
-    if (_recentMessages.contains(message)) {
-      return;
-    }
-
-    // 添加消息到集合中
-    _recentMessages.add(message);
-
-    // 设置定时器,在一定时间后移除消息记录
-    Future.delayed(_deduplicationDuration, () {
-      _recentMessages.remove(message);
-    });
-
-    Fluttertoast.showToast(
-      msg: message,
-      toastLength: toastLength,
-      gravity: gravity,
-      timeInSecForIosWeb: 1,
-      backgroundColor: backgroundColor,
-      textColor: textColor,
-      fontSize: fontSize,
-    );
-  }
 }