show static method
void
show(
- BuildContext context, {
- String? message,
- Widget? child,
- Widget? icon,
- Duration? fadeDuration,
- Duration? duration,
- double? fontSize,
- Color? textColor,
- Color? backgroundColor,
- EdgeInsets? padding,
- BorderRadius? borderRadius,
- BetterToastPosition position = BetterToastPosition.bottom,
- double? topOffset,
- double? bottomOffset,
- TextAlign? textAlign = TextAlign.center,
- bool? forbidClick = false,
- double? width,
- double? height,
- VoidCallback? onHide,
Implementation
static void show(
BuildContext context, {
/// Toast 的消息
String? message,
/// Toast 的子组件
Widget? child,
/// Toast 的图标
Widget? icon,
/// 动画持续时间
Duration? fadeDuration,
/// Toast 的持续时间
Duration? duration,
/// Toast 的字体大小
double? fontSize,
Color? textColor,
/// Toast 的背景颜色
Color? backgroundColor,
/// Toast 的内边距
EdgeInsets? padding,
/// Toast 的圆角半径
BorderRadius? borderRadius,
/// Toast 的位置
BetterToastPosition position = BetterToastPosition.bottom,
/// 顶部偏移量
double? topOffset,
/// 底部偏移量
double? bottomOffset,
/// 文本对齐方式
TextAlign? textAlign = TextAlign.center,
/// 是否禁止点击
bool? forbidClick = false,
/// Toast 的宽度
double? width,
/// Toast 的高度
double? height,
VoidCallback? onHide,
}) {
final overlay = Overlay.of(context);
final screenHeight = BetterScreenUtil.screenHeight;
topOffset ??= screenHeight * 0.2;
bottomOffset ??= screenHeight * 0.2;
// 动画控制器
final animationController = AnimationController(
vsync: overlay,
duration: fadeDuration ?? const Duration(milliseconds: 250),
);
// 遮罩层控制器(仅当 forbidClick=true 时使用)
final fadeController = AnimationController(
vsync: overlay,
duration: const Duration(milliseconds: 150),
);
final fadeAnimation = CurvedAnimation(
parent: fadeController,
curve: Curves.easeInOut,
);
// 位移动画
final offsetAnimation =
Tween<Offset>(
begin: position == BetterToastPosition.center
? Offset.zero
: Offset(0, position == BetterToastPosition.bottom ? 0.1 : -0.1),
end: Offset.zero,
).animate(
CurvedAnimation(
parent: animationController,
curve: Curves.easeOutQuad,
),
);
// 透明度动画
final toastOpacityAnimation = Tween<double>(begin: 0, end: 1).animate(
CurvedAnimation(parent: animationController, curve: Curves.easeIn),
);
// 创建OverlayEntry
final overlayEntry = OverlayEntry(
builder: (context) {
return Stack(
children: [
// 禁止点击的遮罩层(条件渲染)
if (forbidClick == true)
Positioned.fill(
child: FadeTransition(
opacity: fadeAnimation,
child: Container(color: Colors.transparent),
),
),
// Toast内容
Align(
alignment: _getAlignment(position),
child: SlideTransition(
position: offsetAnimation,
child: FadeTransition(
opacity: toastOpacityAnimation,
child: Material(
color: Colors.transparent,
child:
child ??
Container(
width: width,
height: height,
margin: EdgeInsets.only(
top: position == BetterToastPosition.top
? (topOffset ?? 0)
: 0,
bottom: position == BetterToastPosition.bottom
? (bottomOffset ?? 0)
: 0,
),
constraints: BoxConstraints(
maxWidth:
width ?? BetterScreenUtil.screenWidth * 0.8,
),
padding:
padding ??
EdgeInsets.symmetric(
horizontal: 12.bw,
vertical: 8.bw,
),
decoration: BoxDecoration(
color:
backgroundColor ?? Colors.black.withAlpha(178),
borderRadius:
borderRadius ?? BorderRadius.circular(8.bw),
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (icon != null) icon,
if (icon != null && message != null)
SizedBox(height: 8.bw),
if (message != null)
Text(
message,
textAlign: textAlign,
style: TextStyle(
color: textColor ?? Colors.white,
fontSize: fontSize ?? 14.bsp,
),
),
],
),
),
),
),
),
),
],
);
},
);
// 插入到Overlay
overlay.insert(overlayEntry);
// 启动动画(先显示遮罩层)
void startAnimations() async {
if (forbidClick == true) {
await fadeController.forward();
}
await animationController.forward();
}
// 隐藏动画(先隐藏Toast再隐藏遮罩)
Future<void> hideAnimations() async {
await animationController.reverse();
if (forbidClick == true) {
await fadeController.reverse();
}
overlayEntry.remove();
onHide?.call();
}
// 执行显示
startAnimations();
// 延迟隐藏
Future.delayed(duration ?? const Duration(seconds: 2), hideAnimations);
}