/* * @Author: XianKaiQun * @Date: 2020-09-28 14:40:02 * @LastEditors: wuwei * @LastEditTime: 2025-03-28 10:48:45 * @Description: */ import 'package:flutter/material.dart'; import 'package:wisdom_cli/wisdom_cli.dart'; ///loading指示器 class WLoading extends StatelessWidget { const WLoading({ Key? key, this.color = Colors.black26, this.textStyle, this.size, this.strokeWidth, this.text, }) : super(key: key); final Color color; final TextStyle? textStyle; final double? size; final double? strokeWidth; final Widget? text; static TextStyle get defaultTextStyle => TextStyle( color: Colors.black45, fontSize: 14.pt, ); @override Widget build(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, children: [ Container( width: size ?? 40.pt, height: size ?? 40.pt, margin: EdgeInsets.only(right: text != null ? 10 : 0), child: CircularProgressIndicator( strokeWidth: strokeWidth ?? 4.pt, valueColor: AlwaysStoppedAnimation(color), ), ), if (text != null) DefaultTextStyle( style: defaultTextStyle.merge(textStyle), child: text!, ), ], ); } } typedef WLoadingWrapperBuilder = Widget Function( BuildContext context, Future Function()? action, Widget? child, ); ///传入异步事件,加载时显示loading,完成时显示child class WLoadingWrapper extends StatefulWidget { WLoadingWrapper( {Key? key, this.remain = false, this.color, this.textStyle, this.size, this.strokeWidth, this.action, this.text, this.child, this.builder}) : super(key: key); ///加载的时候是否显示loading true不显示,保持child一致,但action依然会失效 ///通常会用在不想显示loading组件,但又要防止多次点击的地方,比如比较快速异步但是又会造成多次点击的地方 final bool remain; final Color? color; final TextStyle? textStyle; final double? size; final double? strokeWidth; final Future Function()? action; final Widget? text; final Widget? child; final WLoadingWrapperBuilder? builder; @override _WLoadingWrapperState createState() => _WLoadingWrapperState(); } class _WLoadingWrapperState extends State { bool loading = false; Future _action() async { if (loading == true) return; widget.action!(); setState(() { loading = true; }); /// 报错 关闭loading if (widget.action != null) { Future.delayed(Duration(milliseconds: 3000)).then((e) => { if (mounted) { loading = false, setState(() {}) } }); } else { loading = false; setState(() {}); } } @override void initState() { super.initState(); } @override Widget build(BuildContext context) { Widget loadingW = WLoading( color: widget.color ?? Theme.of(context).indicatorColor, textStyle: widget.textStyle, size: widget.size ?? 25.pt, strokeWidth: widget.strokeWidth ?? 3.pt, text: widget.text, ); return widget.builder!( context, (loading || widget.action == null) ? null : _action, (loading && !widget.remain) ? loadingW : widget.child, ); } }