Files
flutterApp/lib/components/toast.dart

176 lines
5.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
enum ToastType { success, error, warn, info, loading }
// 自定义Toast工具类 - 气泡式提示
class ToastUtils {
static OverlayEntry? _overlayEntry;
static bool _isShowing = false;
/// 显示气泡提示
/// [context] 上下文
/// [message] 提示文本
/// [backgroundColor] 背景色
/// [duration] 显示时长
/// [positionTop] 距离顶部的高度
static void showToast(
BuildContext context,
String message, {
Color backgroundColor = const Color(0xCC333333),
Duration duration = const Duration(seconds: 1),
double positionTop = 80.0,
}) {
// 先关闭正在显示的提示
if (_isShowing) {
_overlayEntry?.remove();
_isShowing = false;
}
// 创建OverlayEntry
_overlayEntry = OverlayEntry(
builder: (BuildContext context) => Positioned(
top: positionTop,
left: MediaQuery.of(context).size.width * 0.1,
right: MediaQuery.of(context).size.width * 0.1,
child: Material(
color: Colors.transparent,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(18),
boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 10, offset: const Offset(0, 2))],
),
child: Text(
message,
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.white, fontSize: 14, height: 1.2),
),
),
),
),
);
// 显示提示
SchedulerBinding.instance.addPostFrameCallback((_) {
Overlay.of(context).insert(_overlayEntry!);
_isShowing = true;
// 定时关闭
Future.delayed(duration, () {
if (_isShowing) {
_overlayEntry?.remove();
_isShowing = false;
}
});
});
}
/// 显示成功提示(绿色背景 + 85%不透明度)
static void showSuccess(BuildContext context, String message) {
showToast(
context,
message,
// 绿色:0xFF00C853 → 调整为 0xD900C853(D9=85%不透明度)
backgroundColor: const Color(0xD900C853),
duration: const Duration(seconds: 1),
);
}
/// 显示错误提示(红色背景 + 85%不透明度)
static void showError(BuildContext context, String message, {int seconds = 1}) {
showToast(
context,
message,
// 红色:0xFFFF5252 → 调整为 0xD9FF5252(D9=85%不透明度)
backgroundColor: const Color(0xD9FF5252),
duration: Duration(seconds: seconds),
);
}
/// 显示普通提示(灰色背景 + 80%不透明度)
static void showInfo(BuildContext context, String message) {
showToast(
context,
message,
// 灰色:0xCC333333 → 调整为 0xCC333333(保持80%,也可改为 0xB3333333=70%)
backgroundColor: const Color(0xCC333333),
duration: const Duration(seconds: 1),
);
}
/// 显示警告提示(黄色背景 + 85%不透明度)
static void showWarn(BuildContext context, String message) {
showToast(
context,
message,
// 黄色:0xFFFFC107 → 调整为 0xD9FFC107(D9=85%不透明度)
backgroundColor: const Color(0xD9FFC107),
duration: const Duration(seconds: 1),
);
}
/// 显示加载提示(蓝色背景 + 85%不透明度)
static void showLoading(BuildContext context, String message) {
showToast(
context,
message,
// 蓝色:0xFF0688D8 → 调整为 0xD90688D8(D9=85%不透明度)
backgroundColor: const Color(0xD90688D8),
duration: const Duration(seconds: 1),
);
}
// 扩展:支持自定义文字颜色
static void showToastWithTextColor(
BuildContext context,
String message, {
Color backgroundColor = const Color(0xCC333333),
Color textColor = Colors.white,
Duration duration = const Duration(seconds: 2),
double positionTop = 80.0,
}) {
if (_isShowing) {
_overlayEntry?.remove();
_isShowing = false;
}
_overlayEntry = OverlayEntry(
builder: (BuildContext context) => Positioned(
top: positionTop,
left: MediaQuery.of(context).size.width * 0.1,
right: MediaQuery.of(context).size.width * 0.1,
child: Material(
color: Colors.transparent,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(24),
boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 10, offset: const Offset(0, 2))],
),
child: Text(
message,
textAlign: TextAlign.center,
style: TextStyle(color: textColor, fontSize: 14, height: 1.2),
),
),
),
),
);
SchedulerBinding.instance.addPostFrameCallback((_) {
Overlay.of(context).insert(_overlayEntry!);
_isShowing = true;
Future.delayed(duration, () {
if (_isShowing) {
_overlayEntry?.remove();
_isShowing = false;
}
});
});
}
}