1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import 'package:flutter/material.dart';
class Toast {
static ToastView preToast;
static show(BuildContext context, String msg) {
var overlayState = Overlay.of(context);
var controllerShowAnim = new AnimationController(
vsync: overlayState,
duration: Duration(milliseconds: 250),
);
var controllerShowOffset = new AnimationController(
vsync: overlayState,
duration: Duration(milliseconds: 350),
);
var controllerHide = new AnimationController(
vsync: overlayState,
duration: Duration(milliseconds: 250),
);
var opacityAnim1 =
new Tween(begin: 0.0, end: 1.0).animate(controllerShowAnim);
var controllerCurvedShowOffset = new CurvedAnimation(
parent: controllerShowOffset, curve: _BounceOutCurve._());
var offsetAnim =
new Tween(begin: 30.0, end: 0.0).animate(controllerCurvedShowOffset);
var opacityAnim2 = new Tween(begin: 1.0, end: 0.0).animate(controllerHide);
OverlayEntry overlayEntry;
overlayEntry = new OverlayEntry(builder: (context) {
return ToastWidget(
opacityAnim1: opacityAnim1,
opacityAnim2: opacityAnim2,
offsetAnim: offsetAnim,
child: buildToastLayout(msg),
);
});
var toastView = ToastView();
toastView.overlayEntry = overlayEntry;
toastView.controllerShowAnim = controllerShowAnim;
toastView.controllerShowOffset = controllerShowOffset;
toastView.controllerHide = controllerHide;
toastView.overlayState = overlayState;
preToast = toastView;
toastView._show();
}
static LayoutBuilder buildToastLayout(String msg) {
return LayoutBuilder(builder: (context, constraints) {
return IgnorePointer(
ignoring: true,
child: Container(
child: Material(
color: Colors.white.withOpacity(0),
child: Container(
child: Container(
child: Text(
"${msg}",
style: TextStyle(color: Colors.white),
),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.6),
borderRadius: BorderRadius.all(
Radius.circular(5),
),
),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
),
margin: EdgeInsets.only(
bottom: constraints.biggest.height * 0.15,
left: constraints.biggest.width * 0.2,
right: constraints.biggest.width * 0.2,
),
),
),
alignment: Alignment.bottomCenter,
),
);
});
}
}
class ToastView {
OverlayEntry overlayEntry;
AnimationController controllerShowAnim;
AnimationController controllerShowOffset;
AnimationController controllerHide;
OverlayState overlayState;
bool dismissed = false;
_show() async {
overlayState.insert(overlayEntry);
controllerShowAnim.forward();
controllerShowOffset.forward();
await Future.delayed(Duration(milliseconds: 3500));
this.dismiss();
}
dismiss() async {
if (dismissed) {
return;
}
this.dismissed = true;
controllerHide.forward();
await Future.delayed(Duration(milliseconds: 250));
overlayEntry?.remove();
}
}
class ToastWidget extends StatelessWidget {
final Widget child;
final Animation<double> opacityAnim1;
final Animation<double> opacityAnim2;
final Animation<double> offsetAnim;
ToastWidget(
{this.child, this.offsetAnim, this.opacityAnim1, this.opacityAnim2});
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: opacityAnim1,
child: child,
builder: (context, child_to_build) {
return Opacity(
opacity: opacityAnim1.value,
child: AnimatedBuilder(
animation: offsetAnim,
builder: (context, _) {
return Transform.translate(
offset: Offset(0, offsetAnim.value),
child: AnimatedBuilder(
animation: opacityAnim2,
builder: (context, _) {
return Opacity(
opacity: opacityAnim2.value,
child: child_to_build,
);
},
),
);
},
),
);
},
);
}
}
class _BounceOutCurve extends Curve {
const _BounceOutCurve._();
@override
double transform(double t) {
t -= 1.0;
return t * t * ((2 + 1) * t + 2) + 1.0;
}
}