Skip to main content

Add a Loading Indicator Inside a Button After Pressed in Flutter

When you make an internet query, it’s important to show the user that something is happening. One way to do this is by displaying a loading indicator inside of a button after it’s been pressed. This will let the user know that the query is in progress and give them feedback on what’s happening.

We’ve all seen buttons that light up when we press them. They give us feedback that our tap was recognized and the action is being performed. In this snippet, we can use a loading indicator to let the user know that something is happening.

You can make the loading status as a property so it can be modified from outside widget, which calls this NetworkButton.

import 'package:flutter/material.dart';


class NetworkButton extends StatefulWidget {
  final bool? isVertical;
  final Function? onTap;
  final Color? backgroundColor;
  final Color? splashColor;
  final Color? textColor;
  final String? text;
  final TextStyle? textStyle;
  final IconData? iconData;
  final Color? iconColor;
  final double? iconSize;
  final int? delayMls;
  final EdgeInsetsGeometry? edgeInset;

  const NetworkButton({
    Key? key,
    this.onTap,
    this.backgroundColor,
    this.splashColor,
    this.textColor,
    this.text,
    this.iconData,
    this.isVertical,
    this.iconColor,
    this.iconSize,
    this.textStyle,
    this.delayMls,
    this.edgeInset,
  }) : super(key: key);

  @override
  State<NetworkButton> createState() => _NetworkButtonState();
}

class _NetworkButtonState extends State<NetworkButton> with TickerProviderStateMixin {
  bool _visible = true;

  final EdgeInsetsGeometry _edgeInsets = const EdgeInsets.fromLTRB(16.0, 4.0, 16.0, 4.0);

  @override
  void initState() {
    super.initState();
  }

  _onTap() async {
    //change opacity on press
    setState(() {
      _visible = !_visible;
    });

    //carry out action after a small delay to make effect work
    Future.delayed(Duration(milliseconds: widget.delayMls ?? 200), () {
      widget.onTap!();
      _visible = true;
    });
  }


  @override
  Widget build(BuildContext context) {
    return AnimatedOpacity(
      opacity: _visible ? 1.0 : 0.75,
      duration: const Duration(milliseconds: 500),
      child: _visible
          ? Material(
              color: widget.backgroundColor ?? Colors.green,
              borderRadius: CBorderRadius.circular(12.0),
              child: InkWell(
                highlightColor: widget.splashColor ?? Colors.blue,
                splashColor: widget.splashColor ?? Colors.blue,
                borderRadius: CBorderRadius.circular(12.0),
                onTap: _onTap,
                child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                    Icon(widget.iconData, color: Colors.blue),
                    const SizedBox(width: 8),
                    Text(
                        widget.text!,
                        style: widget.textStyle ?? TextStyle(color: Colors.blue),
                    ),
                    ],
                ),
              ),
            )
          : Transform.scale(
              scale: 0.5,
              child: CircularProgressIndicator(
                color: Colors.blue,
              ),
            ),
    );
  }
}

By continuing to use the site, you agree to the use of cookies.