weui_toast.dart 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. part of cool_ui;
  2. class WeuiToast extends TransitionRoute{
  3. OverlayEntry _toastBarrier;
  4. final Widget message;
  5. final Widget icon;
  6. final RouteTransitionsBuilder _transitionBuilder;
  7. final Duration closeDuration;
  8. final Alignment alignment;
  9. WeuiToast({
  10. @required this.message,
  11. @required this.icon,
  12. this.alignment = const Alignment(0.0,-0.2),
  13. Duration transitionDuration = const Duration(milliseconds: 100),
  14. RouteTransitionsBuilder transitionBuilder,
  15. this.closeDuration
  16. }):assert(icon != null),
  17. assert(message!=null),
  18. _transitionDuration = transitionDuration,
  19. _transitionBuilder = transitionBuilder;
  20. @override
  21. void didChangePrevious(Route<dynamic> previousRoute) {
  22. super.didChangePrevious(previousRoute);
  23. changedInternalState();
  24. }
  25. @override
  26. void changedInternalState() {
  27. super.changedInternalState();
  28. _toastBarrier.markNeedsBuild();
  29. }
  30. @override
  31. Iterable<OverlayEntry> createOverlayEntries() sync* {
  32. yield _toastBarrier = OverlayEntry(builder: _buildToastBarrier);
  33. yield OverlayEntry(builder: _buildToastScope, maintainState: true);
  34. }
  35. // TODO: implement opaque
  36. @override
  37. bool get opaque => false;
  38. // TODO: implement transitionDuration
  39. @override
  40. Duration get transitionDuration => _transitionDuration;
  41. final Duration _transitionDuration;
  42. Widget _buildToastBarrier(BuildContext context){
  43. return IgnorePointer(
  44. ignoring: true,
  45. );
  46. }
  47. Widget _buildToastScope(BuildContext context){
  48. return Material(
  49. color: Colors.transparent,
  50. child: Align(
  51. alignment: this.alignment,
  52. child: IntrinsicHeight(
  53. child: AnimatedBuilder(
  54. animation: animation,
  55. builder: (context,child){
  56. return _buildTransition(context,animation,secondaryAnimation,child);
  57. },
  58. child: Container(
  59. width: 122.0,
  60. decoration: BoxDecoration(
  61. color: Color.fromRGBO(17, 17, 17, 0.7),
  62. borderRadius: BorderRadius.circular(5.0)
  63. ),
  64. constraints: BoxConstraints(
  65. minHeight: 122.0,
  66. ),
  67. child: Column(
  68. children: <Widget>[
  69. Container(
  70. margin: EdgeInsets.only(top: 22.0),
  71. constraints:BoxConstraints(
  72. minHeight: 55.0
  73. ) ,
  74. child: IconTheme(data: IconThemeData(color: Colors.white,size: 55.0), child: icon),
  75. ),
  76. DefaultTextStyle(
  77. style: TextStyle(
  78. color: Colors.white,
  79. fontSize: 16.0
  80. ),
  81. child: message,
  82. ),
  83. ],
  84. ),
  85. ),
  86. ),
  87. ),
  88. )
  89. );
  90. }
  91. Widget _buildTransition( BuildContext context,
  92. Animation<double> animation,
  93. Animation<double> secondaryAnimation,
  94. Widget child){
  95. if (_transitionBuilder == null) {
  96. return FadeTransition(
  97. opacity: CurvedAnimation(
  98. parent: animation,
  99. curve: Curves.linear,
  100. ),
  101. child: child);
  102. } // Some default transition
  103. return _transitionBuilder(context, animation, secondaryAnimation, child);
  104. }
  105. }
  106. Future showWeuiSuccessToast({
  107. @required BuildContext context,
  108. Widget message=const Text("成功"),
  109. RouteTransitionsBuilder transitionBuilder,
  110. Alignment alignment = const Alignment(0.0,-0.2),
  111. Duration closeDuration = const Duration(seconds: 3)
  112. }){
  113. var hide = showWeuiToast(
  114. context: context,
  115. alignment: alignment,
  116. message: message,
  117. icon: Icon(CoolUIIcons.success_no_circle),
  118. transitionBuilder:transitionBuilder);
  119. return Future.delayed(closeDuration,(){
  120. hide();
  121. });
  122. }
  123. VoidCallback showWeuiLoadingToast({
  124. @required BuildContext context,
  125. @required Widget message,
  126. Alignment alignment = const Alignment(0.0,-0.2),
  127. RouteTransitionsBuilder transitionBuilder
  128. }){
  129. return showWeuiToast(
  130. context: context,
  131. alignment: alignment,
  132. message: message,
  133. icon: WeuiLoadingIcon(),
  134. transitionBuilder:transitionBuilder);
  135. }
  136. VoidCallback showWeuiToast({
  137. @required BuildContext context,
  138. @required Widget message,
  139. @required Widget icon,
  140. Alignment alignment = const Alignment(0.0,-0.2),
  141. RouteTransitionsBuilder transitionBuilder}){
  142. Completer<VoidCallback> result = Completer<VoidCallback>();
  143. Navigator.of(context,rootNavigator: true).push(
  144. WeuiToast(
  145. alignment: alignment,
  146. message: Builder(builder: (context){
  147. if(!result.isCompleted){
  148. result.complete(()=>Navigator.pop(context));
  149. }
  150. return message;
  151. }),
  152. icon: icon,
  153. transitionBuilder:transitionBuilder));
  154. return (){
  155. result.future.then((hide){
  156. hide();
  157. });
  158. };
  159. }
  160. class WeuiLoadingIcon extends StatefulWidget{
  161. final double size;
  162. WeuiLoadingIcon({this.size = 50.0});
  163. @override
  164. State<StatefulWidget> createState() => WeuiLoadingIconState();
  165. }
  166. class WeuiLoadingIconState extends State<WeuiLoadingIcon>
  167. with SingleTickerProviderStateMixin
  168. {
  169. AnimationController _controller;
  170. Animation<double> _doubleAnimation;
  171. @override
  172. void initState() {
  173. super.initState();
  174. _controller = new AnimationController(
  175. vsync: this, duration: Duration(milliseconds: 1000))
  176. ..repeat();
  177. _doubleAnimation= Tween(begin: 0.0,end: 360.0).animate(_controller)..addListener((){
  178. setState(() {
  179. });
  180. });
  181. }
  182. @override
  183. void dispose() {
  184. // TODO: implement dispose
  185. _controller.dispose();
  186. super.dispose();
  187. }
  188. @override
  189. Widget build(BuildContext context) {
  190. return Transform.rotate(
  191. angle: (_doubleAnimation.value / 30).toInt() * 30.0 * 0.0174533,
  192. child: Image.asset("assets/images/loading.png",
  193. package: "cool_ui",
  194. width: widget.size,
  195. height: widget.size)
  196. );
  197. }
  198. }