• Flutter 支持 Loading 的 Button


    介绍

    Flutter 常见的 loading 框一般是采用 showDialog 的方式弹出一个新的界面,首先并不美观易用,其次,还有一个很大的弊端,因为取消 Loading 框时需要采用 Navigator.pop 方法,会造成严重路由混乱,甚至在一些特殊场景下甚至没有办法实现。

    下图是一个按钮,在点击时会触发相应事件,按钮变为不可点击的 loading 状态,事件执行完成后 loading 状态自动结束,并执行其他逻辑操作。

    代码

    主要代码如下:

    import 'package:flutter/material.dart';
    
    /// 含 Loading 的按钮
    ///
    /// @author seliote
    /// @version 2021-09-08
    
    /// 异步的 VoidCallback,可用于等待执行完成
    typedef AsyncVoidCallback = Future<void> Function();
    
    /// 含 Loading 的按钮
    class LoadingButton extends StatefulWidget {
      final Widget childWidget;
      final Widget loadingWidget;
      final AsyncVoidCallback? callback;
      final VoidCallback? onLongPress;
      final ButtonStyle? style;
      final FocusNode? focusNode;
      final bool autofocus;
      final Clip clipBehavior;
    
      const LoadingButton(this.childWidget, this.loadingWidget, this.callback,
          {Key? key,
          this.onLongPress,
          this.style,
          this.focusNode,
          this.autofocus = false,
          this.clipBehavior = Clip.none})
          : super(key: key);
    
      @override
      _LoadingButtonState createState() => _LoadingButtonState();
    }
    
    class _LoadingButtonState extends State<LoadingButton> {
      bool loading = false;
    
      @override
      Widget build(BuildContext context) {
        return loading
            ? widget.loadingWidget
            : TextButton(
                child: loading ? widget.loadingWidget : widget.childWidget,
                // 保留原始功能,为 null 时或 loading 时禁用按钮
                onPressed: loading
                    ? () => null
                    : (widget.callback == null
                        ? () => null
                        : () async {
                            // 执行前变换
                            setState(() {
                              loading = !loading;
                            });
                            await widget.callback!();
                            // 等待执行完成后再变换
                            setState(() {
                              loading = !loading;
                            });
                          }),
                onLongPress: widget.onLongPress,
                style: widget.style,
                focusNode: widget.focusNode,
                autofocus: widget.autofocus,
                clipBehavior: widget.clipBehavior);
      }
    }
    

    使用

    使用方法如下,其中 SpinKitDoubleBounceflutter_spinkit 库 提供的 Loading 动画:

    LoadingButton(
      Row(
        children: <Widget>[
          Text(
            AppLocalizations.of(globalKey.currentState!.context)!
                .nextStep,
            style: TextStyle(
                color: Colors.lightBlueAccent,
                fontWeight: FontWeight.w600),
          ),
        ],
      ),
      Padding(
        padding: const EdgeInsets.all(8),
        child: SpinKitDoubleBounce(color: Colors.blueAccent),
      ),
      callback,
    )
    
  • 相关阅读:
    list中的对象或者map中的版本号排序 version排序
    spring boot jpa 复杂查询 动态查询 连接and和or 模糊查询 分页查询
    java 8 list的stream操作 list中的对象中的某一个成员取出转为该成员的list,以及对象过滤,筛选某个属性后的成员
    map或者对象转换
    Feign代理必须加value否则启动失败
    Eclipse中.setting目录下文件介绍
    远程仓库版本回退方法
    SpringMVC异常处理机制
    android studio启动和项目编译问题
    CentOS6.5安装php7+nginx+mysql实现安装WordPress
  • 原文地址:https://www.cnblogs.com/seliote/p/15244906.html
Copyright © 2020-2023  润新知