import 'package:oktoast/oktoast.dart' as ok; import 'debug_log.dart'; /// Toast 位置 enum ToastGravity { top, center, bottom } const _duration = Duration(seconds: 2); /// Toast 队列:一条消失后回调里再弹下一条(时序由 oktoast 精确控制) final _queue = <_ToastItem>[]; bool _isShowing = false; class _ToastItem { final String message; final ToastGravity gravity; _ToastItem(this.message, this.gravity); } /// 显示 Toast 消息(连续调用会排队,一条消失后再弹下一条) void showToast(String message, {ToastGravity? gravity}) { if (message.isEmpty) return; // 相邻重复的直接忽略,避免同一句刷屏 if (_queue.isNotEmpty && _queue.last.message == message) return; _queue.add(_ToastItem(message, gravity ?? ToastGravity.center)); _drain(); } void _drain() { if (_isShowing || _queue.isEmpty) return; _isShowing = true; final item = _queue.removeAt(0); var done = false; void next() { if (done) return; done = true; _isShowing = false; _drain(); } try { ok.showToast( item.message, duration: _duration, position: switch (item.gravity) { ToastGravity.top => ok.ToastPosition.top, ToastGravity.bottom => ok.ToastPosition.bottom, ToastGravity.center => ok.ToastPosition.center, }, onDismiss: next, ); } catch (e) { // OKToast 未挂载(启动早期)时 oktoast 直接抛错,不兜住的话 _isShowing 永久为 true → 全 App toast 静默失效 debugLog("showToast()...error:$e"); _queue.clear(); _isShowing = false; return; } // 兜底:toast 被提前 dismiss 或 overlay 已销毁时 oktoast 不回调 onDismiss,超时自愈 Future.delayed(_duration + const Duration(milliseconds: 500), next); }