如何在 Flutter 中定义离散动画?
How to define discrete animation in Flutter?
是否可以在 flutter 中创建一个不会连续更改其值,但仅具有给定时间间隔的动画?
我现在可以使用以下代码,但我确信有更好的解决方案。
int aniValue = 0;
bool lock = false;
_asyncFunc() async {
if(lock) return;
else lock = true;
await new Future.delayed(const Duration(milliseconds: 50), () {
++aniValue;
if (aniValue == 41) {
aniValue = 0;
}
});
lock = false;
setState(() {});
_asyncFunc();
}
可以为动画定义Curve;具有非线性进展。
Flutter 不提供 "step" 曲线,但您可以很容易地制作一条曲线:
class StepCurve extends Curve {
final int stepCount;
const StepCurve([this.stepCount = 2]) : assert(stepCount > 1);
@override
double transform(double t) {
final progress = (t * stepCount).truncate();
return 1 / (stepCount - 1) * progress;
}
}
然后您可以通过将其关联到 CurveTween
来自由使用它:
@override
Widget build(BuildContext context) {
return AlignTransition(
alignment: AlignmentGeometryTween(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
)
.chain(CurveTween(curve: const StepCurve(5)))
.animate(animationController),
child: Container(
color: Colors.red,
width: 42.0,
height: 42.0,
),
);
}
另一个解决方案是使用 TweenSequence。
class TestAnim extends StatefulWidget {
@override
_TestAnimState createState() => _TestAnimState();
}
class _TestAnimState extends State<TestAnim>
with SingleTickerProviderStateMixin {
AnimationController animationController;
@override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
)..repeat();
}
@override
Widget build(BuildContext context) {
final colors = <Color>[
Colors.red,
Colors.blue,
Colors.lime,
Colors.purple,
];
return DecoratedBoxTransition(
decoration: TweenSequence(colorsToTween(colors).toList())
.animate(animationController),
child: const SizedBox.expand(),
);
}
}
Iterable<TweenSequenceItem<Decoration>> colorsToTween(
List<Color> colors) sync* {
for (int i = 0; i < colors.length - 1; i++) {
yield TweenSequenceItem<Decoration>(
tween: DecorationTween(
begin: BoxDecoration(color: colors[i]),
end: BoxDecoration(color: colors[i + 1]),
),
weight: 1.0,
);
}
}
是否可以在 flutter 中创建一个不会连续更改其值,但仅具有给定时间间隔的动画?
我现在可以使用以下代码,但我确信有更好的解决方案。
int aniValue = 0;
bool lock = false;
_asyncFunc() async {
if(lock) return;
else lock = true;
await new Future.delayed(const Duration(milliseconds: 50), () {
++aniValue;
if (aniValue == 41) {
aniValue = 0;
}
});
lock = false;
setState(() {});
_asyncFunc();
}
可以为动画定义Curve;具有非线性进展。
Flutter 不提供 "step" 曲线,但您可以很容易地制作一条曲线:
class StepCurve extends Curve {
final int stepCount;
const StepCurve([this.stepCount = 2]) : assert(stepCount > 1);
@override
double transform(double t) {
final progress = (t * stepCount).truncate();
return 1 / (stepCount - 1) * progress;
}
}
然后您可以通过将其关联到 CurveTween
来自由使用它:
@override
Widget build(BuildContext context) {
return AlignTransition(
alignment: AlignmentGeometryTween(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
)
.chain(CurveTween(curve: const StepCurve(5)))
.animate(animationController),
child: Container(
color: Colors.red,
width: 42.0,
height: 42.0,
),
);
}
另一个解决方案是使用 TweenSequence。
class TestAnim extends StatefulWidget {
@override
_TestAnimState createState() => _TestAnimState();
}
class _TestAnimState extends State<TestAnim>
with SingleTickerProviderStateMixin {
AnimationController animationController;
@override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
)..repeat();
}
@override
Widget build(BuildContext context) {
final colors = <Color>[
Colors.red,
Colors.blue,
Colors.lime,
Colors.purple,
];
return DecoratedBoxTransition(
decoration: TweenSequence(colorsToTween(colors).toList())
.animate(animationController),
child: const SizedBox.expand(),
);
}
}
Iterable<TweenSequenceItem<Decoration>> colorsToTween(
List<Color> colors) sync* {
for (int i = 0; i < colors.length - 1; i++) {
yield TweenSequenceItem<Decoration>(
tween: DecorationTween(
begin: BoxDecoration(color: colors[i]),
end: BoxDecoration(color: colors[i + 1]),
),
weight: 1.0,
);
}
}