Button 009 — Flutter Button Widget

Free copy-paste Button 009 for Flutter: a ready-to-use button widget with full Dart source code and a live preview. Works on desktop. No external packages.

  • Category: Buttons
  • Platforms: desktop
  • Flutter SDK only — no external packages
  • Free to copy & use

How to use Button 009 in Flutter

Copy the Dart code below into a new file in your Flutter project (for example lib/widgets/button_009.dart) and use the widget anywhere in your widget tree.

Button 009 – Dart source code

import 'package:flutter/material.dart';

class Button009 extends StatefulWidget {
  const Button009({
    super.key,
    this.label = 'BUTTON',
    this.onTap,
    this.color = Colors.white,
    this.textColor = Colors.black,
    this.fontSize = 17.0,
    this.padding = const EdgeInsets.symmetric(horizontal: 40, vertical: 16),
    this.rippleDuration = const Duration(milliseconds: 1000),
  });

  final String label;
  final VoidCallback? onTap;
  final Color color, textColor;
  final double fontSize;
  final EdgeInsetsGeometry padding;
  final Duration rippleDuration;

  @override
  State<Button009> createState() => _Button009State();
}

class _Button009State extends State<Button009>
    with SingleTickerProviderStateMixin {
  late final AnimationController _pulse;
  late final Animation<double> _scaleX, _scaleY, _opacity;
  bool _hovered = false, _pressed = false;

  @override
  void initState() {
    super.initState();
    _pulse = AnimationController(vsync: this, duration: widget.rippleDuration);
    final scaleCurve = CurvedAnimation(
      parent: _pulse,
      curve: Curves.easeOutQuad,
    );
    final opacityCurve = CurvedAnimation(parent: _pulse, curve: Curves.easeIn);
    _scaleX = Tween<double>(begin: 1.0, end: 1.4).animate(scaleCurve);
    _scaleY = Tween<double>(begin: 1.0, end: 1.6).animate(scaleCurve);
    _opacity = Tween<double>(begin: 0.75, end: 0.0).animate(opacityCurve);
  }

  @override
  void didUpdateWidget(covariant Button009 oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.rippleDuration != widget.rippleDuration) {
      _pulse.duration = widget.rippleDuration;
    }
  }

  @override
  void dispose() {
    _pulse.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final y = _pressed ? -1.0 : (_hovered ? -3.0 : 0.0);
    final shadow = BoxShadow(
      color: Colors.black.withValues(alpha: _hovered ? 0.22 : 0.08),
      blurRadius: _pressed ? 10.0 : (_hovered ? 20.0 : 6.0),
      offset: Offset(0, _pressed ? 5.0 : (_hovered ? 10.0 : 2.0)),
    );

    return MouseRegion(
      opaque: true,
      cursor: SystemMouseCursors.click,
      onEnter: (_) {
        setState(() => _hovered = true);
        _pulse.forward(from: 0.0);
      },
      onExit: (_) {
        setState(() => _hovered = false);
      },
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTapDown: (_) {
          setState(() => _pressed = true);
          _pulse.forward(from: 0.0);
        },
        onTapUp: (_) {
          setState(() => _pressed = false);
          widget.onTap?.call();
        },
        onTapCancel: () => setState(() => _pressed = false),
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 200),
          curve: Curves.easeOut,
          transform: Matrix4.translationValues(0.0, y, 0.0),
          child: Stack(
            alignment: Alignment.center,
            clipBehavior: Clip.none,
            children: [
              AnimatedBuilder(
                animation: _pulse,
                builder: (context, _) {
                  if (!_pulse.isAnimating && !_hovered) {
                    return const SizedBox.shrink();
                  }
                  return IgnorePointer(
                    child: Transform.scale(
                      scaleX: _scaleX.value,
                      scaleY: _scaleY.value,
                      child: Opacity(
                        opacity: _opacity.value.clamp(0.0, 1.0),
                        child: DecoratedBox(
                          decoration: BoxDecoration(
                            color: widget.color,
                            borderRadius: BorderRadius.circular(100),
                          ),
                          child: Padding(
                            padding: widget.padding,
                            child: Text(
                              widget.label.toUpperCase(),
                              style: TextStyle(
                                color: Colors.transparent,
                                fontSize: widget.fontSize,
                                fontWeight: FontWeight.w500,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                  );
                },
              ),
              AnimatedContainer(
                duration: const Duration(milliseconds: 200),
                curve: Curves.easeOut,
                padding: widget.padding,
                decoration: BoxDecoration(
                  color: widget.color,
                  borderRadius: BorderRadius.circular(100),
                  boxShadow: [shadow],
                ),
                child: Text(
                  widget.label.toUpperCase(),
                  style: TextStyle(
                    color: widget.textColor,
                    fontSize: widget.fontSize,
                    fontWeight: FontWeight.w500,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

More Flutter Buttons