flutter_number_flow 0.1.0
flutter_number_flow: ^0.1.0 copied to clipboard
Animated Flutter widget for smooth number transitions. Perfect for counters, currency displays, and statistics with locale support.
Flutter Number Flow #
A beautiful Flutter widget that animates number changes with smooth, customizable transitions. Perfect for displaying animated counters, currency values, statistics, and more with a professional, polished look.
โจ Features #
- ๐ฏ Smooth Number Animations: Animate only the digits that change, keeping unchanged digits stable
- ๐จ Multiple Animation Styles: Choose between slide and crossFade animations for different visual effects
- ๐ Locale-Aware Formatting: Support for different locales, currencies, and number formats using
intl
- ๐ Compact Notation: Display large numbers in compact format (1.2K, 1.5M, 2.1B)
- โก High Performance: Optimized with text metrics caching and tabular figures for consistent layout
- ๐๏ธ Group Synchronization: Synchronize animations across multiple NumberFlow widgets
- ๐ฎ Manual Control: Drive animations manually with scrub progress for timeline controls
- โฟ Accessibility: Proper semantics support for screen readers
- ๐ญ Customizable: Full control over text styles, animation duration, and curves
- ๐ฑ Material 3: Built with Material Design 3 principles
๐ฑ Demo #
![]() Mobile App |
![]() Web App |
๐ฑ Live Demo #
Try the interactive web demo to see all features in action.
๐ Quick Start #
Installation #
Add flutter_number_flow
to your pubspec.yaml
:
dependencies:
flutter_number_flow: ^0.1.0
Then run:
flutter pub get
Basic Usage #
import 'package:flutter/material.dart';
import 'package:flutter_number_flow/flutter_number_flow.dart';
class CounterExample extends StatefulWidget {
@override
_CounterExampleState createState() => _CounterExampleState();
}
class _CounterExampleState extends State<CounterExample> {
double _value = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
NumberFlow(
value: _value,
textStyle: const TextStyle(
fontSize: 48,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 32),
ElevatedButton(
onPressed: () => setState(() => _value += 1),
child: const Text('Increment'),
),
],
),
),
);
}
}
๐จ Animation Styles #
Slide Animation #
Numbers slide vertically when changing, creating a smooth rolling effect:
NumberFlow(
value: 1234.56,
animationStyle: NumberFlowAnimation.slide,
duration: const Duration(milliseconds: 600),
)
CrossFade Animation #
Numbers fade between old and new values for a subtle transition:
NumberFlow(
value: 1234.56,
animationStyle: NumberFlowAnimation.crossFade,
duration: const Duration(milliseconds: 400),
)
๐ Formatting & Localization #
Currency Formatting #
NumberFlow(
value: 1234.56,
format: const NumberFlowFormat(
prefix: '\$',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
),
textStyle: const TextStyle(
fontSize: 32,
color: Colors.green,
fontWeight: FontWeight.bold,
),
)
Compact Notation #
Display large numbers in a readable format:
NumberFlow(
value: 1500000,
format: const NumberFlowFormat(
notation: NumberNotation.compact,
maximumFractionDigits: 1,
),
) // Displays "1.5M"
Locale Support #
NumberFlow(
value: 1234.56,
format: const NumberFlowFormat(
locale: 'de_DE', // German locale
minimumFractionDigits: 2,
),
) // Displays "1.234,56"
๐๏ธ Advanced Features #
Group Synchronization #
Synchronize animations across multiple widgets:
NumberFlowGroupProvider(
groupKey: 'financials',
duration: const Duration(milliseconds: 800),
child: Column(
children: [
NumberFlow(
value: revenue,
groupKey: 'financials',
format: const NumberFlowFormat(prefix: '\$'),
),
NumberFlow(
value: expenses,
groupKey: 'financials',
format: const NumberFlowFormat(prefix: '\$'),
),
],
),
)
Manual Animation Control #
Drive animations manually for timeline scrubbing:
class ScrubExample extends StatefulWidget {
@override
_ScrubExampleState createState() => _ScrubExampleState();
}
class _ScrubExampleState extends State<ScrubExample> {
double _progress = 0.0;
final double _startValue = 0;
final double _endValue = 1000000;
@override
Widget build(BuildContext context) {
final currentValue = _startValue + (_endValue - _startValue) * _progress;
return Column(
children: [
NumberFlow(
value: currentValue,
scrubProgress: _progress,
format: const NumberFlowFormat(
prefix: '\$',
notation: NumberNotation.compact,
),
),
Slider(
value: _progress,
onChanged: (value) => setState(() => _progress = value),
),
],
);
}
}
๐ API Reference #
NumberFlow Widget #
Property | Type | Default | Description |
---|---|---|---|
value |
num |
required | Current number value to display |
previousValue |
num? |
null |
Previous value for animation (auto-detected if null) |
textStyle |
TextStyle? |
null |
Text style for the number display |
animationStyle |
NumberFlowAnimation |
slide |
Animation style (slide or crossFade) |
duration |
Duration |
600ms |
Animation duration |
curve |
Curve |
easeInOut |
Animation curve |
format |
NumberFlowFormat? |
null |
Number formatting options |
textAlign |
TextAlign |
center |
Text alignment |
groupKey |
String? |
null |
Group key for synchronization |
scrubProgress |
double? |
null |
Manual animation progress (0.0-1.0) |
enableMask |
bool |
true |
Enable edge masking for smooth clipping |
NumberFlowFormat #
Property | Type | Default | Description |
---|---|---|---|
locale |
String? |
null |
Locale for number formatting |
notation |
NumberNotation |
standard |
Number notation (standard or compact) |
prefix |
String? |
null |
Text to display before the number |
suffix |
String? |
null |
Text to display after the number |
minimumFractionDigits |
int? |
null |
Minimum decimal places |
maximumFractionDigits |
int? |
null |
Maximum decimal places |
NumberFlowAnimation #
enum NumberFlowAnimation {
slide, // Vertical sliding animation
crossFade, // Opacity transition animation
}
NumberNotation #
enum NumberNotation {
standard, // 1,234,567
compact, // 1.2M
}
๐ฏ Performance #
Flutter Number Flow is optimized for performance:
- Text Metrics Caching: Glyph dimensions are cached to avoid repeated calculations
- Tabular Figures: Uses
FontFeature.tabularFigures()
for consistent digit widths - Efficient Diffing: Only animates digits that actually change
- Minimal Rebuilds: Smart widget composition minimizes unnecessary rebuilds
โฟ Accessibility #
The widget follows Flutter accessibility best practices:
- Semantic Labels: Screen readers announce the complete number value
- Proper Focus: Supports keyboard navigation and focus management
- High Contrast: Works well with system accessibility settings
๐งช Testing #
The package includes comprehensive tests:
flutter test
Run golden tests to verify visual output:
flutter test --update-goldens
๐ค Contributing #
Contributions are welcome! Please read our contributing guide and code of conduct.
Development Setup #
-
Clone the repository:
git clone https://github.com/example/flutter_number_flow.git cd flutter_number_flow
-
Get dependencies:
flutter pub get
-
Run the example:
cd example flutter run
-
Run tests:
flutter test
๐ License #
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments #
- Inspired by the number-flow React library
- Built with Flutter and Dart
- Uses the intl package for internationalization
๐ Changelog #
See CHANGELOG.md for a detailed list of changes and migration guides.
๐ฌ Support #
- ๐ Documentation
- ๐ Issue Tracker
- ๐ฌ Discussions
- ๐ง Email Support
Made with โค๏ธ by the Flutter Number Flow team