Some checks failed
Release / meta (push) Successful in 18s
Release / android-build (push) Successful in 11m48s
Release / linux-build (push) Successful in 1m24s
Release / web-build (push) Successful in 6m15s
Release / release-dev (push) Has been cancelled
Release / release-master (push) Has been cancelled
82 lines
2.2 KiB
Dart
82 lines
2.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
class AnimatedCountText extends StatefulWidget {
|
|
const AnimatedCountText({
|
|
super.key,
|
|
required this.value,
|
|
required this.formatter,
|
|
this.style,
|
|
this.duration = const Duration(milliseconds: 900),
|
|
this.curve = Curves.easeOutCubic,
|
|
this.animateFromZero = true,
|
|
});
|
|
|
|
final double value;
|
|
final String Function(double) formatter;
|
|
final TextStyle? style;
|
|
final Duration duration;
|
|
final Curve curve;
|
|
final bool animateFromZero;
|
|
|
|
@override
|
|
State<AnimatedCountText> createState() => _AnimatedCountTextState();
|
|
}
|
|
|
|
class _AnimatedCountTextState extends State<AnimatedCountText>
|
|
with SingleTickerProviderStateMixin {
|
|
late AnimationController _controller;
|
|
late Animation<double> _animation;
|
|
late CurvedAnimation _curve;
|
|
double _currentValue = 0;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_currentValue = widget.animateFromZero ? 0 : widget.value;
|
|
_controller = AnimationController(vsync: this, duration: widget.duration);
|
|
_curve = CurvedAnimation(parent: _controller, curve: widget.curve);
|
|
_controller.addListener(_handleTick);
|
|
_configureAnimation(from: _currentValue, to: widget.value);
|
|
if (_currentValue != widget.value) {
|
|
_controller.forward();
|
|
}
|
|
}
|
|
|
|
@override
|
|
void didUpdateWidget(covariant AnimatedCountText oldWidget) {
|
|
super.didUpdateWidget(oldWidget);
|
|
if (oldWidget.curve != widget.curve) {
|
|
_curve = CurvedAnimation(parent: _controller, curve: widget.curve);
|
|
_configureAnimation(from: _currentValue, to: widget.value);
|
|
}
|
|
if (oldWidget.value != widget.value) {
|
|
_controller.duration = widget.duration;
|
|
_configureAnimation(from: _currentValue, to: widget.value);
|
|
_controller.forward(from: 0);
|
|
}
|
|
}
|
|
|
|
void _configureAnimation({required double from, required double to}) {
|
|
_animation = Tween<double>(begin: from, end: to).animate(_curve);
|
|
}
|
|
|
|
void _handleTick() {
|
|
setState(() => _currentValue = _animation.value);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_controller.removeListener(_handleTick);
|
|
_controller.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Text(
|
|
widget.formatter(_currentValue),
|
|
style: widget.style,
|
|
);
|
|
}
|
|
}
|