Как запустить анимацию до завершения другой анимации с той же скоростью (продолжительностью)

#flutter #flutter-layout #flutter-animation

#flutter #flutter-макет #flutter-анимация

Вопрос:

Как запустить анимацию до завершения другой анимации с той же скоростью (продолжительностью).

Я попытался сделать это с помощью контроллера анимации и анимации double с интервалом, первая анимация выполняется так, как я ожидал, но вторая анимация выполняется быстрее, чем первая. Я думаю, это произошло потому, что второй интервал анимации был установлен на 0,5, 1.

Это то, что я пытался использовать с интервалом, но вторая анимация быстрее первой

 class Ex extends StatefulWidget {
  @override
  _ExState createState() => _ExState();
}

class _ExState extends State<Ex> with SingleTickerProviderStateMixin {
  AnimationController animationController;

  Animation<double> animation1;
  Animation<double> animation2;
  Animation<double> opacityAnimation;

  @override
  void initState() {
    super.initState();
    animationController =
        AnimationController(vsync: this, duration: Duration(seconds: 3));

    animation1 = Tween<double>(
      begin: 250,
      end: 300,
    ).animate(
        CurvedAnimation(curve: Interval(0, 1), parent: animationController))
      ..addListener(() {
        setState(() {});
      })
      ..addStatusListener((status) {
        print(status);
        if (status == AnimationStatus.completed) {
          animationController.reset();
        } else if (status == AnimationStatus.dismissed) {
          animationController.forward();
        }
      });

    animation2 = Tween<double>(
      begin: 250,
      end: 300,
    ).animate(
        CurvedAnimation(curve: Interval(0.5, 1), parent: animationController))
      ..addListener(() {
        setState(() {});
      })
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          animationController.reset();
        } else if (status == AnimationStatus.dismissed) {
          animationController.forward();
        }
      });

    opacityAnimation = Tween<double>(
      begin: 1,
      end: 0,
    ).animate(animationController)
      ..addListener(() {
        setState(() {});
      });

    animationController.forward();
  }

  @override
  Widget build(BuildContext context) {
    double radius = MediaQuery.of(context).size.height / 4;
    return Scaffold(
      body: Stack(
        children: [
          AnimatedCircle(
              height: animation1.value,
              width: animation1.value,
              opacity: opacityAnimation.value,
              radius: radius),
          AnimatedCircle(
              height: animation2.value,
              width: animation2.value,
              opacity: opacityAnimation.value,
              radius: radius),
          AnimatedCircle(height: 250, width: 250, opacity: 1, radius: radius),
        ],
      ),
    );
  }
}
 

Класс AnimatedCircle:

 class AnimatedCircle extends StatelessWidget {
  final double height;
  final double width;
  final double opacity;
  final double radius;
  AnimatedCircle(
      {@required this.height,
      @required this.width,
      @required this.opacity,
      @required this.radius});
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        height: height,
        width: width,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.only(
            topRight: Radius.circular(radius),
            topLeft: Radius.circular(radius),
            bottomLeft: Radius.circular(radius),
            bottomRight: Radius.circular(radius),
          ),
          border: Border.all(
            width: 1.5,
            color: Colors.green.withOpacity(opacity),
            style: BorderStyle.solid,
          ),
        ),
      ),
    );
  }
}
 

Ответ №1:

Вы можете попробовать использовать анимацию в шахматном порядке, чтобы укладывать больше анимаций одну за другой и выбирать начальный и конечный интервал анимации.

В вашем текущем случае у второй анимации меньше времени для завершения, поэтому она выполняется быстрее. В конечном итоге вы можете задать один интервал анимации (0, 0.5) и для второго (0.5, 1)

Надеюсь, это было хоть как-то полезно. Приветствия