首页 > 解决方案 > 如何在颤动中启动间隔动画

问题描述

我想制作三个落在屏幕上的球的动画。但我希望第一个球的动画比第二个球的动画开始得早,第二个球的动画比第三个球的动画开始得早一点。

我试图在动画的前进之间给予某种超时,但由于某种原因没有奏效。在下面的代码中,我为三个球完成了相同的动画。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
  AnimationController animationController1,
      animationController2,
      animationController3;

  Animation<double> animation, animation2, animation3;

  @override
  void initState() {
    animationController1 =
        AnimationController(duration: Duration(milliseconds: 300), vsync: this);
    animationController2 =
        AnimationController(duration: Duration(milliseconds: 300), vsync: this);
    animationController3 =
        AnimationController(duration: Duration(milliseconds: 300), vsync: this);

    animation = Tween(
      begin: 0.0,
      end: 1.0,
    ).animate(
      CurvedAnimation(parent: animationController1, curve: Interval(0.0, 1.0)),
    );

    animation2 = Tween(
      begin: 0.0,
      end: 1.0,
    ).animate(
      CurvedAnimation(parent: animationController2, curve: Interval(1.0, 2.0)),
    );

    animation3 = Tween(
      begin: 0.0,
      end: 1.0,
    ).animate(
      CurvedAnimation(parent: animationController3, curve: Interval(2.0, 3.0)),
    );

    animationController1.addListener(() {
      print('1 ${animation.value}');
      print('2 ${animation.value}');
      print('3 ${animation.value}');
      setState(() {});
    });

    animationController1.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        animationController1.reverse();
      } else if (status == AnimationStatus.dismissed) {
        animationController1.forward();
      }
    });
    animationController2.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        animationController2.reverse();
      } else if (status == AnimationStatus.dismissed) {
        animationController2.forward();
      }
    });
    animationController3.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        animationController3.reverse();
      } else if (status == AnimationStatus.dismissed) {
        animationController3.forward();
      }
    });

    animationController1.forward();
    animationController2.forward();
    animationController3.forward();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          child: Center(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                buildBallOne(),
                SizedBox(
                  width: 6.0,
                ),
                buildBallTwo(),
                SizedBox(
                  width: 6.0,
                ),
                buildBallThree()
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget buildBallOne() {
    return Container(
      margin: EdgeInsets.only(top: 100 - (animationController1.value * 50)),
      width: 35,
      height: 35,
      decoration: ShapeDecoration(
        shape: CircleBorder(),
        color: Colors.blue,
      ),
    );
  }

  Widget buildBallTwo() {
    return Container(
      margin: EdgeInsets.only(top: 100 - (animationController2.value * 50)),
      width: 35,
      height: 35,
      decoration: ShapeDecoration(
        shape: CircleBorder(),
        color: Colors.blue,
      ),
    );
  }

  Widget buildBallThree() {
    return Container(
      margin: EdgeInsets.only(top: 100 - (animationController3.value * 50)),
      width: 35,
      height: 35,
      decoration: ShapeDecoration(
        shape: CircleBorder(),
        color: Colors.blue,
      ),
    );
  }
}

标签: flutterflutter-animation

解决方案


那是因为您同时运行所有控制器。

在此处输入图像描述

我只是增加了延迟并做了一些曲调。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
  AnimationController animationController1, animationController2, animationController3;

  Animation<double> animation1, animation2, animation3;

  @override
  void initState() {
    animationController1 = AnimationController(
      duration: Duration(milliseconds: 600),
      vsync: this,
    );
    animationController2 = AnimationController(
      duration: Duration(milliseconds: 600),
      vsync: this,
    );
    animationController3 = AnimationController(
      duration: Duration(milliseconds: 600),
      vsync: this,
    );

    animation1 = Tween(
      begin: 0.0,
      end: 1.0,
    ).animate(
      CurvedAnimation(parent: animationController1, curve: Interval(0.0, 1.0)),
    );

    animation2 = Tween(
      begin: 0.0,
      end: 1.0,
    ).animate(
      CurvedAnimation(parent: animationController2, curve: Interval(0.0, 1.0)),
    );

    animation3 = Tween(
      begin: 0.0,
      end: 1.0,
    ).animate(
      CurvedAnimation(parent: animationController3, curve: Interval(0.0, 1.0)),
    );

    animationController1.addListener(() {
      print('1 ${animation1?.value}');
      print('2 ${animation2?.value}');
      print('3 ${animation3?.value}');
      setState(() {});
    });

    animationController1.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        animationController1.reverse();
      } else if (status == AnimationStatus.dismissed) {
        animationController1.forward();
      }
    });
    animationController2.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        animationController2.reverse();
      } else if (status == AnimationStatus.dismissed) {
        animationController2.forward();
      }
    });
    animationController3.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        animationController3.reverse();
      } else if (status == AnimationStatus.dismissed) {
        animationController3.forward();
      }
    });

    Future.delayed(
      Duration(milliseconds: 300),
      () => animationController1.forward(),
    );

    Future.delayed(
      Duration(milliseconds: 600),
      () => animationController2.forward(),
    );
    Future.delayed(
      Duration(milliseconds: 900),
      () => animationController3.forward(),
    );

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          child: Center(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                buildBallOne(),
                SizedBox(
                  width: 6.0,
                ),
                buildBallTwo(),
                SizedBox(
                  width: 6.0,
                ),
                buildBallThree()
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget buildBallOne() {
    return Container(
      margin: EdgeInsets.only(top: 100 - (animationController1.value * 50)),
      width: 35,
      height: 35,
      decoration: ShapeDecoration(
        shape: CircleBorder(),
        color: Colors.blue,
      ),
    );
  }

  Widget buildBallTwo() {
    return Container(
      margin: EdgeInsets.only(top: 100 - (animationController2.value * 50)),
      width: 35,
      height: 35,
      decoration: ShapeDecoration(
        shape: CircleBorder(),
        color: Colors.blue,
      ),
    );
  }

  Widget buildBallThree() {
    return Container(
      margin: EdgeInsets.only(top: 100 - (animationController3.value * 50)),
      width: 35,
      height: 35,
      decoration: ShapeDecoration(
        shape: CircleBorder(),
        color: Colors.blue,
      ),
    );
  }
}

实际上,因为所有球的动画路径都相同,所以您可以使用一个控制器并为每个球计算不同的位置

ps使用Animated Widget或AnimatedBuilder,不触发setState刷新页面,会提供更好的性能。


推荐阅读