loading.dart 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * @Author: XianKaiQun
  3. * @Date: 2020-09-28 14:40:02
  4. * @LastEditors: wuwei
  5. * @LastEditTime: 2025-03-28 10:48:45
  6. * @Description:
  7. */
  8. import 'package:flutter/material.dart';
  9. import 'package:wisdom_cli/wisdom_cli.dart';
  10. ///loading指示器
  11. class WLoading extends StatelessWidget {
  12. const WLoading({
  13. Key? key,
  14. this.color = Colors.black26,
  15. this.textStyle,
  16. this.size,
  17. this.strokeWidth,
  18. this.text,
  19. }) : super(key: key);
  20. final Color color;
  21. final TextStyle? textStyle;
  22. final double? size;
  23. final double? strokeWidth;
  24. final Widget? text;
  25. static TextStyle get defaultTextStyle => TextStyle(
  26. color: Colors.black45,
  27. fontSize: 14.pt,
  28. );
  29. @override
  30. Widget build(BuildContext context) {
  31. return Row(
  32. mainAxisSize: MainAxisSize.min,
  33. children: <Widget>[
  34. Container(
  35. width: size ?? 40.pt,
  36. height: size ?? 40.pt,
  37. margin: EdgeInsets.only(right: text != null ? 10 : 0),
  38. child: CircularProgressIndicator(
  39. strokeWidth: strokeWidth ?? 4.pt,
  40. valueColor: AlwaysStoppedAnimation(color),
  41. ),
  42. ),
  43. if (text != null)
  44. DefaultTextStyle(
  45. style: defaultTextStyle.merge(textStyle),
  46. child: text!,
  47. ),
  48. ],
  49. );
  50. }
  51. }
  52. typedef WLoadingWrapperBuilder = Widget Function(
  53. BuildContext context,
  54. Future<void> Function()? action,
  55. Widget? child,
  56. );
  57. ///传入异步事件,加载时显示loading,完成时显示child
  58. class WLoadingWrapper extends StatefulWidget {
  59. WLoadingWrapper(
  60. {Key? key,
  61. this.remain = false,
  62. this.color,
  63. this.textStyle,
  64. this.size,
  65. this.strokeWidth,
  66. this.action,
  67. this.text,
  68. this.child,
  69. this.builder})
  70. : super(key: key);
  71. ///加载的时候是否显示loading true不显示,保持child一致,但action依然会失效
  72. ///通常会用在不想显示loading组件,但又要防止多次点击的地方,比如比较快速异步但是又会造成多次点击的地方
  73. final bool remain;
  74. final Color? color;
  75. final TextStyle? textStyle;
  76. final double? size;
  77. final double? strokeWidth;
  78. final Future<void> Function()? action;
  79. final Widget? text;
  80. final Widget? child;
  81. final WLoadingWrapperBuilder? builder;
  82. @override
  83. _WLoadingWrapperState createState() => _WLoadingWrapperState();
  84. }
  85. class _WLoadingWrapperState extends State<WLoadingWrapper> {
  86. bool loading = false;
  87. Future<void> _action() async {
  88. if (loading == true) return;
  89. widget.action!();
  90. setState(() {
  91. loading = true;
  92. });
  93. /// 报错 关闭loading
  94. if (widget.action != null) {
  95. Future.delayed(Duration(milliseconds: 3000)).then((e) => {
  96. if (mounted) {
  97. loading = false,
  98. setState(() {})
  99. }
  100. });
  101. } else {
  102. loading = false;
  103. setState(() {});
  104. }
  105. }
  106. @override
  107. void initState() {
  108. super.initState();
  109. }
  110. @override
  111. Widget build(BuildContext context) {
  112. Widget loadingW = WLoading(
  113. color: widget.color ?? Theme.of(context).indicatorColor,
  114. textStyle: widget.textStyle,
  115. size: widget.size ?? 25.pt,
  116. strokeWidth: widget.strokeWidth ?? 3.pt,
  117. text: widget.text,
  118. );
  119. return widget.builder!(
  120. context,
  121. (loading || widget.action == null) ? null : _action,
  122. (loading && !widget.remain) ? loadingW : widget.child,
  123. );
  124. }
  125. }