progress_dialog.dart 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/painting.dart';
  4. enum ProgressDialogType { Normal, Download }
  5. String _dialogMessage = "Loading...";
  6. double _progress = 0.0, _maxProgress = 100.0;
  7. Widget _customBody;
  8. TextAlign _textAlign = TextAlign.left;
  9. Alignment _progressWidgetAlignment = Alignment.centerLeft;
  10. TextDirection _direction = TextDirection.ltr;
  11. bool _isShowing = false;
  12. BuildContext _context, _dismissingContext;
  13. ProgressDialogType _progressDialogType;
  14. bool _barrierDismissible = true, _showLogs = false;
  15. Color _barrierColor;
  16. TextStyle _progressTextStyle = TextStyle(
  17. color: Colors.black,
  18. fontSize: 12.0,
  19. fontWeight: FontWeight.w400,
  20. ),
  21. _messageStyle = TextStyle(
  22. color: Colors.black,
  23. fontSize: 18.0,
  24. fontWeight: FontWeight.w600,
  25. );
  26. double _dialogElevation = 8.0, _borderRadius = 8.0;
  27. Color _backgroundColor = Colors.white;
  28. Curve _insetAnimCurve = Curves.easeInOut;
  29. EdgeInsets _dialogPadding = const EdgeInsets.all(8.0);
  30. Widget _progressWidget = Image.asset(
  31. 'assets/double_ring_loading_io.gif',
  32. package: 'progress_dialog',
  33. );
  34. class ProgressDialog {
  35. _Body _dialog;
  36. ProgressDialog(
  37. BuildContext context, {
  38. ProgressDialogType type,
  39. bool isDismissible,
  40. bool showLogs,
  41. TextDirection textDirection,
  42. Widget customBody,
  43. Color barrierColor,
  44. }) {
  45. _context = context;
  46. _progressDialogType = type ?? ProgressDialogType.Normal;
  47. _barrierDismissible = isDismissible ?? true;
  48. _showLogs = showLogs ?? false;
  49. _customBody = customBody ?? null;
  50. _direction = textDirection ?? TextDirection.ltr;
  51. _barrierColor = barrierColor ?? barrierColor;
  52. }
  53. void style({
  54. Widget child,
  55. double progress,
  56. double maxProgress,
  57. String message,
  58. Widget progressWidget,
  59. Color backgroundColor,
  60. TextStyle progressTextStyle,
  61. TextStyle messageTextStyle,
  62. double elevation,
  63. TextAlign textAlign,
  64. double borderRadius,
  65. Curve insetAnimCurve,
  66. EdgeInsets padding,
  67. Alignment progressWidgetAlignment,
  68. }) {
  69. if (_isShowing) return;
  70. if (_progressDialogType == ProgressDialogType.Download) {
  71. _progress = progress ?? _progress;
  72. }
  73. _dialogMessage = message ?? _dialogMessage;
  74. _maxProgress = maxProgress ?? _maxProgress;
  75. _progressWidget = progressWidget ?? _progressWidget;
  76. _backgroundColor = backgroundColor ?? _backgroundColor;
  77. _messageStyle = messageTextStyle ?? _messageStyle;
  78. _progressTextStyle = progressTextStyle ?? _progressTextStyle;
  79. _dialogElevation = elevation ?? _dialogElevation;
  80. _borderRadius = borderRadius ?? _borderRadius;
  81. _insetAnimCurve = insetAnimCurve ?? _insetAnimCurve;
  82. _textAlign = textAlign ?? _textAlign;
  83. _progressWidget = child ?? _progressWidget;
  84. _dialogPadding = padding ?? _dialogPadding;
  85. _progressWidgetAlignment =
  86. progressWidgetAlignment ?? _progressWidgetAlignment;
  87. }
  88. void update({
  89. double progress,
  90. double maxProgress,
  91. String message,
  92. Widget progressWidget,
  93. TextStyle progressTextStyle,
  94. TextStyle messageTextStyle,
  95. }) {
  96. if (_progressDialogType == ProgressDialogType.Download) {
  97. _progress = progress ?? _progress;
  98. }
  99. _dialogMessage = message ?? _dialogMessage;
  100. _maxProgress = maxProgress ?? _maxProgress;
  101. _progressWidget = progressWidget ?? _progressWidget;
  102. _messageStyle = messageTextStyle ?? _messageStyle;
  103. _progressTextStyle = progressTextStyle ?? _progressTextStyle;
  104. if (_isShowing) _dialog.update();
  105. }
  106. bool isShowing() {
  107. return _isShowing;
  108. }
  109. Future<bool> hide() async {
  110. try {
  111. if (_isShowing) {
  112. _isShowing = false;
  113. Navigator.of(_dismissingContext).pop();
  114. if (_showLogs) debugPrint('ProgressDialog dismissed');
  115. return Future.value(true);
  116. } else {
  117. if (_showLogs) debugPrint('ProgressDialog already dismissed');
  118. return Future.value(false);
  119. }
  120. } catch (err) {
  121. debugPrint('Seems there is an issue hiding dialog');
  122. debugPrint(err.toString());
  123. return Future.value(false);
  124. }
  125. }
  126. Future<bool> show() async {
  127. try {
  128. if (!_isShowing) {
  129. _dialog = new _Body();
  130. showDialog<dynamic>(
  131. context: _context,
  132. barrierDismissible: _barrierDismissible,
  133. barrierColor: _barrierColor,
  134. builder: (BuildContext context) {
  135. _dismissingContext = context;
  136. return WillPopScope(
  137. onWillPop: () async => _barrierDismissible,
  138. child: Dialog(
  139. backgroundColor: _backgroundColor,
  140. insetAnimationCurve: _insetAnimCurve,
  141. insetAnimationDuration: Duration(milliseconds: 100),
  142. elevation: _dialogElevation,
  143. shape: RoundedRectangleBorder(
  144. borderRadius:
  145. BorderRadius.all(Radius.circular(_borderRadius)),
  146. ),
  147. child: _dialog,
  148. ),
  149. );
  150. },
  151. );
  152. // Delaying the function for 200 milliseconds
  153. // [Default transitionDuration of DialogRoute]
  154. await Future.delayed(Duration(milliseconds: 200));
  155. if (_showLogs) debugPrint('ProgressDialog shown');
  156. _isShowing = true;
  157. return true;
  158. } else {
  159. if (_showLogs) debugPrint("ProgressDialog already shown/showing");
  160. return false;
  161. }
  162. } catch (err) {
  163. _isShowing = false;
  164. debugPrint('Exception while showing the dialog');
  165. debugPrint(err.toString());
  166. return false;
  167. }
  168. }
  169. }
  170. // ignore: must_be_immutable
  171. class _Body extends StatefulWidget {
  172. final _BodyState _dialog = _BodyState();
  173. update() {
  174. _dialog.update();
  175. }
  176. @override
  177. State<StatefulWidget> createState() {
  178. return _dialog;
  179. }
  180. }
  181. class _BodyState extends State<_Body> {
  182. update() {
  183. setState(() {});
  184. }
  185. @override
  186. void dispose() {
  187. _isShowing = false;
  188. if (_showLogs) debugPrint('ProgressDialog dismissed by back button');
  189. super.dispose();
  190. }
  191. @override
  192. Widget build(BuildContext context) {
  193. final loader = Align(
  194. alignment: _progressWidgetAlignment,
  195. child: SizedBox(
  196. width: 60.0,
  197. height: 60.0,
  198. child: _progressWidget,
  199. ),
  200. );
  201. final text = Expanded(
  202. child: _progressDialogType == ProgressDialogType.Normal
  203. ? Text(
  204. _dialogMessage,
  205. textAlign: _textAlign,
  206. style: _messageStyle,
  207. textDirection: _direction,
  208. )
  209. : Padding(
  210. padding: const EdgeInsets.all(8.0),
  211. child: Column(
  212. mainAxisSize: MainAxisSize.min,
  213. children: <Widget>[
  214. SizedBox(height: 8.0),
  215. Row(
  216. children: <Widget>[
  217. Expanded(
  218. child: Text(
  219. _dialogMessage,
  220. style: _messageStyle,
  221. textDirection: _direction,
  222. ),
  223. ),
  224. ],
  225. ),
  226. SizedBox(height: 4.0),
  227. Align(
  228. alignment: Alignment.bottomRight,
  229. child: Text(
  230. "$_progress/$_maxProgress",
  231. style: _progressTextStyle,
  232. textDirection: _direction,
  233. ),
  234. ),
  235. ],
  236. ),
  237. ),
  238. );
  239. return _customBody ??
  240. Container(
  241. padding: _dialogPadding,
  242. child: Column(
  243. mainAxisSize: MainAxisSize.min,
  244. children: <Widget>[
  245. // row body
  246. Row(
  247. mainAxisSize: MainAxisSize.min,
  248. children: <Widget>[
  249. const SizedBox(width: 8.0),
  250. _direction == TextDirection.ltr ? loader : text,
  251. const SizedBox(width: 8.0),
  252. _direction == TextDirection.rtl ? loader : text,
  253. const SizedBox(width: 8.0)
  254. ],
  255. ),
  256. ],
  257. ),
  258. );
  259. }
  260. }