-
-
Save bluemix/4c932e8c4a1cd6f497a4353d9e536f57 to your computer and use it in GitHub Desktop.
class AnimatedCount extends ImplicitlyAnimatedWidget { | |
AnimatedCount({ | |
Key? key, | |
required this.count, | |
Duration duration = const Duration(milliseconds: 600), | |
Curve curve = Curves.fastOutSlowIn, | |
}) : super(duration: duration, curve: curve, key: key); | |
final num count; | |
@override | |
ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState() { | |
return _AnimatedCountState(); | |
} | |
} | |
class _AnimatedCountState extends AnimatedWidgetBaseState<AnimatedCount> { | |
IntTween _intCount = IntTween(begin: 0, end: 1); | |
Tween<double> _doubleCount = Tween<double>(); | |
@override | |
Widget build(BuildContext context) { | |
return widget.count is int | |
? Text(_intCount.evaluate(animation).toString()) | |
: Text(_doubleCount.evaluate(animation).toStringAsFixed(1)); | |
} | |
@override | |
void forEachTween(TweenVisitor<dynamic> visitor) { | |
if (widget.count is int) { | |
_intCount = visitor( | |
_intCount, | |
widget.count, | |
(dynamic value) => IntTween(begin: value), | |
) as IntTween; | |
} else { | |
_doubleCount = visitor( | |
_doubleCount, | |
widget.count, | |
(dynamic value) => Tween<double>(begin: value), | |
) as Tween<double>; | |
} | |
} | |
} |
Hello. Same here. Did you find a workaround?
I have an exception here:
_doubleCount = visitor(
Exception:
Exception has occurred. _CastError (type 'Null' is not a subtype of type 'double' in type cast)
Only when I use doubles. Integers working as expected.
I changed this line:
Tween<double> _doubleCount = Tween<double>();
To:
Tween<double> _doubleCount = Tween<double>(begin: 0, end: 1);
and it seems to be ok
Would there be a way to change the duration based on the number value delta? For example, having the duration at 2000ms when the number is changing from 0 to 100, vs having the duration at 300ms when the number is changing from 0-5 ?
This is so cool
Another issue I have faced that it not animating in first render. to fix that I have added the initState
:
import 'package:flutter/material.dart';
class AnimatedCount extends ImplicitlyAnimatedWidget {
const AnimatedCount({
Key? key,
required this.count,
this.style,
Duration duration = const Duration(milliseconds: 600),
Curve curve = Curves.fastOutSlowIn,
this.prefix = '',
this.suffix = '',
}) : super(duration: duration, curve: curve, key: key);
final num count;
final String prefix;
final String suffix;
final TextStyle? style;
@override
ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState() {
return _AnimatedCountState();
}
}
class _AnimatedCountState extends AnimatedWidgetBaseState<AnimatedCount> {
IntTween _intCount = IntTween(begin: 0, end: 1);
Tween<double> _doubleCount = Tween<double>(begin: 0, end: 1);
@override
void initState() {
super.initState();
if (widget.count is int) {
_intCount = IntTween(begin: 0, end: widget.count.toInt());
} else {
_doubleCount = Tween<double>(begin: 0, end: widget.count.toDouble());
}
controller.forward();
}
@override
Widget build(BuildContext context) {
final String text;
if (widget.count is int) {
final countStr = _intCount.evaluate(animation).toString();
text = '${widget.prefix}$countStr${widget.suffix}';
} else {
final countStr = _doubleCount.evaluate(animation).toStringAsFixed(1);
text = '${widget.prefix}$countStr${widget.suffix}';
}
return Text(text, style: widget.style);
}
@override
void forEachTween(TweenVisitor<dynamic> visitor) {
if (widget.count is int) {
_intCount = visitor(
_intCount,
widget.count,
(dynamic value) => IntTween(begin: value),
) as IntTween;
} else {
_doubleCount = visitor(
_doubleCount,
widget.count,
(dynamic value) => Tween<double>(begin: value),
) as Tween<double>;
}
}
}
Extra: added suffix and prefix arguments.
Another issue I have faced that it not animating in first render. to fix that I have added the
initState
:import 'package:flutter/material.dart'; class AnimatedCount extends ImplicitlyAnimatedWidget { const AnimatedCount({ Key? key, required this.count, this.style, Duration duration = const Duration(milliseconds: 600), Curve curve = Curves.fastOutSlowIn, this.prefix = '', this.suffix = '', }) : super(duration: duration, curve: curve, key: key); final num count; final String prefix; final String suffix; final TextStyle? style; @override ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState() { return _AnimatedCountState(); } } class _AnimatedCountState extends AnimatedWidgetBaseState<AnimatedCount> { IntTween _intCount = IntTween(begin: 0, end: 1); Tween<double> _doubleCount = Tween<double>(begin: 0, end: 1); @override void initState() { super.initState(); if (widget.count is int) { _intCount = IntTween(begin: 0, end: widget.count.toInt()); } else { _doubleCount = Tween<double>(begin: 0, end: widget.count.toDouble()); } controller.forward(); } @override Widget build(BuildContext context) { final String text; if (widget.count is int) { final countStr = _intCount.evaluate(animation).toString(); text = '${widget.prefix}$countStr${widget.suffix}'; } else { final countStr = _doubleCount.evaluate(animation).toStringAsFixed(1); text = '${widget.prefix}$countStr${widget.suffix}'; } return Text(text, style: widget.style); } @override void forEachTween(TweenVisitor<dynamic> visitor) { if (widget.count is int) { _intCount = visitor( _intCount, widget.count, (dynamic value) => IntTween(begin: value), ) as IntTween; } else { _doubleCount = visitor( _doubleCount, widget.count, (dynamic value) => Tween<double>(begin: value), ) as Tween<double>; } } }Extra: added suffix and prefix arguments.
This works for me, thanks 👍
I have an exception here:
_doubleCount = visitor(
Exception:
Exception has occurred. _CastError (type 'Null' is not a subtype of type 'double' in type cast)
Only when I use doubles. Integers working as expected.