如何在Flutter中定义离散动画?

时间:2018-09-11 17:22:22

标签: dart flutter flutter-layout flutter-animation

是否可以在不连续改变其值的情况下,仅在给定的时间间隔内创建抖动动画?

我现在正在运行以下代码,但是我敢肯定有更好的解决方案。

  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();
  }

1 个答案:

答案 0 :(得分:3)

可以为动画定义“曲线”;具有非线性级数。

Flutter不提供“阶梯”曲线,但是您可以轻松地制作出一条曲线:

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,
    ),
  );
}

enter image description here


另一种解决方案是使用TweenSequence

enter image description here

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,
    );
  }
}