1 import ‘package:flutter/material.dart‘; 2 3 enum ToastPosition { top, center, bottom } 4 5 class Toast { 6 static OverlayEntry _overlayEntry; 7 static bool _showing = false; 8 static ToastPosition toastPosition; 9 static DateTime _startTime; 10 static String _msg; 11 static void show(BuildContext context, 12 {String msg, 13 int duration = 1, // 默认1秒 14 ToastPosition toastPosition, 15 Color background = const Color(0xB2000000), 16 TextStyle textStyle = const TextStyle( 17 fontSize: 16, 18 color: Colors.white, 19 backgroundColor: Colors.transparent), 20 double backgroundRadius = 20, 21 Border border}) async { 22 OverlayState overlayState = Overlay.of(context); 23 toastPosition = ToastPosition.center; 24 _startTime = DateTime.now(); 25 _showing = true; 26 _msg = msg; 27 if (_overlayEntry == null) { 28 _overlayEntry = OverlayEntry( 29 builder: (BuildContext context) => 30 ToastWidget( 31 widget: Container( 32 width: MediaQuery.of(context).size.width, 33 child: Container( 34 alignment: Alignment.center, 35 width: MediaQuery.of(context).size.width, 36 child: Container( 37 decoration: BoxDecoration( 38 color: background, 39 borderRadius: BorderRadius.circular(backgroundRadius), 40 border: border, 41 ), 42 margin: EdgeInsets.symmetric(horizontal: 20), 43 padding: EdgeInsets.symmetric(vertical: 5, horizontal: 20), 44 child: Text(_msg, softWrap: true, style: textStyle), 45 )), 46 ), 47 toastPosition: toastPosition), 48 ); 49 overlayState.insert(_overlayEntry); 50 } else { 51 //重新绘制UI,类似setState 52 _overlayEntry.markNeedsBuild(); 53 } 54 await Future.delayed(Duration(seconds: duration)); 55 if (DateTime.now().difference(_startTime).inSeconds >= duration) { 56 // 如果当前时间与toast显示的开始时间差大于等于显示时间就消失 否则继续显示 57 dismiss(); 58 } 59 } 60 61 static dismiss() async { 62 if (!_showing) { 63 return; 64 } 65 _showing = false; 66 _overlayEntry?.remove(); 67 _overlayEntry = null; 68 } 69 } 70 71 class ToastWidget extends StatelessWidget { 72 ToastWidget({ 73 Key key, 74 @required this.widget, 75 this.toastPosition, 76 }) : super(key: key); 77 78 final Widget widget; 79 final ToastPosition toastPosition; 80 81 @override 82 Widget build(BuildContext context) { 83 return Positioned( 84 top: buildToastPosition(context), 85 child: Material( 86 color: Colors.transparent, 87 child: widget, 88 )); 89 } 90 91 double buildToastPosition(context) { 92 var top; 93 if (toastPosition == ToastPosition.top) { 94 top = MediaQuery.of(context).size.height * 1 / 4; 95 } else if (toastPosition == ToastPosition.center) { 96 top = MediaQuery.of(context).size.height * 2 / 5; 97 } else { 98 top = MediaQuery.of(context).size.height * 3 / 4; 99 } 100 return top; 101 } 102 }
调用 Toast.show(context, msg: ‘显示toast‘, duration: 5);
可以一直触发toast并且更新文本内容、直到需要显示的时间结束后消失
原文:https://www.cnblogs.com/rakan0225/p/13098673.html