toast弹窗优化
This commit is contained in:
173
lib/components/toast.dart
Normal file
173
lib/components/toast.dart
Normal file
@@ -0,0 +1,173 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
|
||||
// 自定义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) {
|
||||
showToast(
|
||||
context,
|
||||
message,
|
||||
// 红色:0xFFFF5252 → 调整为 0xD9FF5252(D9=85%不透明度)
|
||||
backgroundColor: const Color(0xD9FF5252),
|
||||
duration: const Duration(seconds: 1),
|
||||
);
|
||||
}
|
||||
|
||||
/// 显示普通提示(灰色背景 + 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;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user