答案 0 :(得分:6)
我想在一个项目中执行此操作,因此我创建了一个称为AnimatedFlipCounter
的隐式动画小部件,该控件实现了类似的效果。
用法:
AnimatedFlipCounter(
duration: Duration(milliseconds: 500),
value: _value, /* pass in a number like 2014 */
color: Colors.black,
size: 100,
)
源代码:
只需将以下内容复制并粘贴到文件中,然后像上面的示例一样使用AnimatedFlipCounter
。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class AnimatedFlipCounter extends StatelessWidget {
final int value;
final Duration duration;
final double size;
final Color color;
const AnimatedFlipCounter({
Key key,
@required this.value,
@required this.duration,
this.size = 72,
this.color = Colors.black,
}) : super(key: key);
@override
Widget build(BuildContext context) {
List<int> digits = value == 0 ? [0] : [];
int v = value;
if (v < 0) {
v *= -1;
}
while (v > 0) {
digits.add(v);
v = v ~/ 10;
}
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(digits.length, (int i) {
return _SingleDigitFlipCounter(
key: ValueKey(digits.length - i),
value: digits[digits.length - i - 1].toDouble(),
duration: duration,
height: size,
width: size / 1.8,
color: color,
);
}),
);
}
}
class _SingleDigitFlipCounter extends StatelessWidget {
final double value;
final Duration duration;
final double height;
final double width;
final Color color;
const _SingleDigitFlipCounter({
Key key,
@required this.value,
@required this.duration,
@required this.height,
@required this.width,
@required this.color,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder(
tween: Tween(begin: value, end: value),
duration: duration,
builder: (context, value, child) {
final whole = value ~/ 1;
final decimal = value - whole;
return SizedBox(
height: height,
width: width,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
_buildSingleDigit(
digit: whole % 10,
offset: height * decimal,
opacity: 1 - decimal,
),
_buildSingleDigit(
digit: (whole + 1) % 10,
offset: height * decimal - height,
opacity: decimal,
),
],
),
);
},
);
}
Widget _buildSingleDigit({int digit, double offset, double opacity}) {
return Positioned(
child: SizedBox(
width: width,
child: Opacity(
opacity: opacity,
child: Text(
"$digit",
style: TextStyle(fontSize: height, color: color),
textAlign: TextAlign.center,
),
),
),
bottom: offset,
);
}
}
答案 1 :(得分:0)
我在动画生成器中使用补间动画
IntTween(begin: 0, end: starredCount).animate(
CurvedAnimation(parent: animationController, curve: Curves.easeOut)
答案 2 :(得分:0)
您应该通过以下方式实现
class ValueChangeAnimationWidget extends StatefulWidget {
@override
ValueChangeAnimationWidgetState createState() =>
ValueChangeAnimationWidgetState();
}
class ValueChangeAnimationWidgetState
extends State<ValueChangeAnimationWidget> with TickerProviderStateMixin {
AnimationController controller;
Animation animation;
@override
void initState() {
super.initState();
controller = AnimationController(
duration: const Duration(milliseconds: 1000), vsync: this);
final Animation curve =
CurvedAnimation(parent: controller, curve: Curves.easeOut);
animation = IntTween(begin: 0, end: 10).animate(curve)
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
}
if (status == AnimationStatus.dismissed) {
Navigator.pop(context);
}
});
}
@override
Widget build(BuildContext context) {
controller.forward();
return AnimatedBuilder(
animation: controller,
builder: (BuildContext context, Widget child) {
return Scaffold(
body: new Center(
child: Text(animation.value.toString(), style: TextStyle(fontSize: 48.0)),
));
});
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
}