flutter 实现一个有加载动画的按钮(loadingButton)

前言

今天分享一个又加载动画的按钮,希望能帮助到你,替换加载图标就可以了。效果图如下:
在这里插入图片描述

在这里插入图片描述

一、loading组件代码
import "dart:math" as math;

import 'package:flutter/material.dart';

class HBLoadingButton extends StatefulWidget {
  bool loading;
  String title;
  Function callback;
  bool isActive; //是否活跃
  // 按钮高度
  double? height = 40.0;

  HBLoadingButton(this.loading, this.title, this.callback, {this.height, this.isActive = true});

  @override
  _HBLoadingButtonState createState() => _HBLoadingButtonState();
}

class _HBLoadingButtonState extends State<HBLoadingButton> with SingleTickerProviderStateMixin {
  AnimationController? _controller;

  @override
  void initState() {
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 100 * 15),
    )..repeat();
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  Widget _btn() {
    return Container(
      decoration: widget.isActive
          ? BoxDecoration(
              color: Color(0xFF006CFF),
              borderRadius: BorderRadius.circular(8.0),
            )
          : BoxDecoration(
              color: Color(0x1F0C0C1C),
              borderRadius: BorderRadius.circular(8.0),
            ),
      height: widget.height,
      child: TextButton(
        style: ButtonStyle(
          foregroundColor: MaterialStateProperty.all(Color(0xFF006CFF)),
        ),
        child: Text(
          widget.title,
          style: widget.isActive
              ? const TextStyle(fontSize: 16.0, color: Color(0xFFFFFFFF))
              : const TextStyle(fontSize: 16.0, color: Color(0x800C0C1C)),
        ),
        onPressed: () {
          widget.callback();
        },
      ),
    );
  }

  Widget _loadingBtn() {
    Widget icon = Image.asset(
      "lib/common/assets/ic_loading_more_white.png",
      width: 16,
      height: 16,
    );

    if (_controller != null) {
      icon = AnimatedBuilder(
        animation: _controller!,
        builder: (_, Widget? child) {
          return Transform.rotate(
            angle: _controller!.value * 2 * math.pi,
            child: child,
          );
        },
        child: icon,
      );
    }

    return Container(
      decoration: BoxDecoration(
        color: Color(0xFF006CFF),
        borderRadius: BorderRadius.circular(8.0),
      ),
      height: widget.height,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Text(
            "加载中。。。",
            style: TextStyle(color: Color(0xFFFFFFFF), fontSize: 14.0),
          ),
          Container(
            margin: const EdgeInsets.only(left: 6.0),
            child: icon,
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return widget.loading ? _loadingBtn() : _btn();
  }
}

二、使用代码
import 'package:flutter/material.dart';
import 'package:flutter_hotsmeta/module/beginner_guide/page/hb_loading_button.dart';

class HBLoadingPage extends StatefulWidget {
  const HBLoadingPage({Key? key}) : super(key: key);

  @override
  State<HBLoadingPage> createState() => _HBLoadingPageState();
}

class _HBLoadingPageState extends State<HBLoadingPage> {
  bool requesting = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: AppBar(
        title: Text("测试加载按钮"),
      ),
      body: _buildMainWidget(context),
    );
  }

  _buildMainWidget(BuildContext context) {
    return Center(
      child: SizedBox(
        width: 291.0,
        height: 40.0,
        child: HBLoadingButton(
          requesting,
          "确定",
          _beforeConfirm,
        ),
      ),
    );
  }

  _beforeConfirm() {
    setState(() {
      requesting = true;
    });
    Future.delayed(const Duration(milliseconds: 5000), () {
      setState(() {
        requesting = false;
      });
    });
  }
}

END.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明似水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值