Flutter Animation Stepper

A Flutter package for creating beautiful horizontal steppers with smooth animations and customizable themes.

Features

  • Two Stepper Widgets:
    • AnimationStepper: Traditional stepper with icons, titles, and subtitles
    • MovingDotStepper: Minimal dot-based stepper with smooth transitions
  • Smooth Animations: Elegant transitions between step states with customizable animation curves
  • Fully Customizable: Control colors, sizes, fonts, and animation durations through theme
  • Custom Icons: Support for custom icons in all states (inactive, active, completed) including SVG
  • Loading Indicator: Built-in support for showing loading state on specific steps
  • Step Navigation: Tap on steps to navigate with onStepTapped callback
  • Flexible Widgets: Support for any widget type in steps (Icon, Image, SVG, etc.)
  • Layout Options: Choose between connected or separated line layouts
  • Horizontal Scrolling: Automatically handles overflow with horizontal scrolling

Getting Started

Add this to your package's pubspec.yaml file:

dependencies:
  flutter_animation_stepper: ^2.0.1

Then run:

flutter pub get

Usage

Basic Example

import 'package:flutter_animation_stepper/flutter_animation_stepper.dart';

AnimationStepper(
  steps: [
    StepItem(
      icon: Icon(Icons.shopping_cart),
      title: 'Cart',
      subtitle: 'Review items',
    ),
    StepItem(
      icon: Icon(Icons.payment),
      title: 'Payment',
      subtitle: 'Enter details',
    ),
    StepItem(
      icon: Icon(Icons.check_circle),
      title: 'Confirm',
      subtitle: 'Complete order',
    ),
  ],
  currentStep: 1,
  onStepTapped: (index) {
    setState(() => currentStep = index);
  },
)

With Custom Theme

AnimationStepper(
  steps: steps,
  currentStep: currentStep,
  theme: AnimationStepperTheme(
    activeColor: Colors.blue,
    completeColor: Colors.green,
    inactiveColor: Colors.grey,
    loadingColor: Colors.orange,
    iconSize: 32,
    lineHeight: 4,
  ),
  onStepTapped: (index) {
    setState(() => currentStep = index);
  },
)

With Loading Indicator

AnimationStepper(
  steps: steps,
  currentStep: currentStep,
  loadingStep: 1, // Show loading on step 1
  onStepTapped: (index) {
    setState(() => currentStep = index);
  },
)

MovingDotStepper - Basic Usage

import 'package:flutter_animation_stepper/flutter_animation_stepper.dart';

// Steps are evenly distributed across the available width
// Control width using a parent Container or Expanded widget
Container(
  width: 400, // Or use Expanded for flexible width
  child: MovingDotStepper(
    stepCount: 4,
    currentStep: 1,
    stepLabels: ['Start', 'Process', 'Review', 'Complete'],
    onStepTapped: (index) {
      setState(() => currentStep = index);
    },
  ),
)

MovingDotStepper - With Custom Icons

Container(
  width: double.infinity, // Fill available width
  child: MovingDotStepper(
    stepCount: 4,
    currentStep: 1,
    stepLabels: ['Start', 'Process', 'Review', 'Complete'],
    inactiveIcon: Icon(Icons.radio_button_unchecked, color: Colors.grey, size: 16),
    activeIcon: Icon(Icons.play_circle_filled, color: Colors.white, size: 16),
    completedIcon: Icon(Icons.check_circle, color: Colors.white, size: 16),
    theme: MovingDotStepperTheme(
      activeColor: Colors.blue,
      completedColor: Colors.green,
      dotSize: 28.0,
      lineInset: 4.0, // Optional: spacing between dots and lines
    ),
    onStepTapped: (index) {
      setState(() => currentStep = index);
    },
  ),
)

MovingDotStepper - With SVG Icons

import 'package:flutter_svg/flutter_svg.dart';

Expanded(
  child: MovingDotStepper(
    stepCount: 3,
    currentStep: 0,
    inactiveIcon: SvgPicture.asset('assets/icons/inactive.svg', width: 16, height: 16),
    activeIcon: SvgPicture.asset('assets/icons/active.svg', width: 16, height: 16),
    completedIcon: SvgPicture.asset('assets/icons/completed.svg', width: 16, height: 16),
    onStepTapped: (index) {
      setState(() => currentStep = index);
    },
  ),
)

MovingDotStepper - With Custom Dot Widgets

Replace the entire dot structure (not just the icon) with custom widgets:

Container(
  width: 400,
  child: MovingDotStepper(
    stepCount: 4,
    currentStep: 1,
    stepLabels: ['Start', 'Process', 'Review', 'Complete'],
    // Custom square dots instead of circles
    completedDot: Container(
      width: 28,
      height: 28,
      decoration: BoxDecoration(
        color: Colors.green,
        borderRadius: BorderRadius.circular(4),
      ),
      child: Icon(Icons.check, color: Colors.white, size: 16),
    ),
    activeDot: Container(
      width: 28,
      height: 28,
      decoration: BoxDecoration(
        color: Colors.blue,
        borderRadius: BorderRadius.circular(4),
      ),
      child: Icon(Icons.edit, color: Colors.white, size: 16),
    ),
    inactiveDot: Container(
      width: 28,
      height: 28,
      decoration: BoxDecoration(
        color: Colors.transparent,
        borderRadius: BorderRadius.circular(4),
        border: Border.all(color: Colors.grey, width: 2),
      ),
    ),
    onStepTapped: (index) {
      setState(() => currentStep = index);
    },
  ),
)

Additional Information

For more examples, check out the /example folder in the repository.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Issues

If you encounter any issues, please report them on GitHub Issues.

License

This project is licensed under the MIT License.