多个 Flutter 动画一个接一个地不起作用

Multiple Flutter animation not working one after the other

我是 flutter 的新手,目前我正在尝试制作一个简单的应用程序,当应用程序打开时,文本会出现 fadeIn 并更改其 position from bottom to top。是的,有两个 animations 我想要 Transit。第一个是 FadeIn 完成后继续进行下一个 animationPosition Transition 将文本的 Vertical 位置从 400.0 更改至 200.0 pixels.

我能够实现淡入过程,但没有应用第一个位置。 首先,我希望 FadeIn TextAnimation 在完成后启动我想启动 PositionAnimation,不是同时启动,而是在动画完成后一个接一个地启动。

代码如下:

class _SplashScreenState extends State<SplashScreen>
 with TickerProviderStateMixin {
 AnimationController animationController;
 double position = 400.0;
 Animation<double> _animation;
 Tween<double> tween;

  @override
    void initState() {
    super.initState();

    animationController = AnimationController(
    vsync: this,
    duration: Duration(milliseconds: 700),
  );

   _animation = CurvedAnimation(
   parent: animationController,
   curve: Curves.easeIn,
 );

   tween = Tween(begin: 400, end: 200);

   animationController.forward();
}

 @override
  Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.amber,
    body: FadeTransition(
      opacity: _animation,

      child: Padding(
        padding: EdgeInsets.symmetric(
            vertical:_animation.isCompleted? tween : position,
            horizontal: 180.0),
        child: Text(
          'My Life',
          style: TextStyle(
              fontWeight: FontWeight.bold,
              fontSize: 30.0,
              color: Colors.white70,
              letterSpacing: 2.0),
        ),
      ),
    ),
  );
}

 @override
  void dispose() {
  animationController.dispose();
  super.dispose();
 }
}

任何专业知识,因为我是新手,所以我不确定我做错了什么。请指导我,任何人。

这是我今天尝试过但仍然没有得到结果的更新代码:

class _SplashScreenState extends State<SplashScreen>
  with TickerProviderStateMixin {
AnimationController animationControllerFade;
AnimationController animationControllerPost;
double position = 400.0;
FadeTransition fadeTransition;
Animation<double> animation;
int i = 0;

@override
void initState() {
   super.initState();

   animationControllerFade = AnimationController(
      vsync: this,
    duration: Duration(milliseconds: 700),
   );
   animationControllerPost = AnimationController(
     vsync: this,
   duration: Duration(milliseconds: 700),
   );

   animation = CurvedAnimation(
     parent: animationControllerFade,
     curve: Curves.easeIn,
   );

   animationControllerFade.forward();
 }

 @override
 Widget build(BuildContext context) {
   Scaffold sc;
   sc = Scaffold(
     backgroundColor: Colors.amber,
   );

   fadeTransition = FadeTransition(
     opacity: animation,
     child: paddingOwn(position),
   );

   animationControllerFade.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
       animationControllerPost.forward();
       sc = Scaffold(
          body: TweenAnimationBuilder(
          curve: Curves.easeIn,
          duration: Duration(milliseconds: 700),
          tween: Tween<double>(begin: 400.0, end: 200.0),
          builder: (BuildContext context, double val, Widget child) {
            return Positioned(child: paddingOwn(val));
           },
          ),
        );
       } 
       else {
          sc = Scaffold(body: fadeTransition);
       }
     });

     return sc;
   }

   Widget paddingOwn(double val) {
      return Padding(
        padding: EdgeInsets.symmetric(
        vertical: val,
        horizontal: 180,
      ),
      child: Text(
        'My Life',
        style: TextStyle(
           fontWeight: FontWeight.bold,
           fontSize: 30.0,
           color: Colors.white70,
           letterSpacing: 2.0),
      ),
     );
    }

    @override
    void dispose() {
      animationControllerFade.dispose();
      animationControllerPost.dispose();
      super.dispose();
    }
   }

仍然没有结果。

如果要获取位置转换,需要使用SlideTransition

此外,您需要为 Tween 设置动画,以便正确插值。

我稍微更改了您的代码,以便将文本居中并从那里设置动画。无论如何,请记住 SlideTransition 适用于 Offsets in a relative way from the size of the child

现在,您应该能够根据您想要实现的最终结果调整此代码:

class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMixin {
  AnimationController _fadeAnimationController;
  AnimationController _slideAnimationController;
  double position = 400.0;
  Animation<double> _fadeAnimation;
  Animation<Offset> _slideAnimation;

  @override
  void initState() {
    super.initState();

    _fadeAnimationController = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 700),
    );

    _slideAnimationController = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 700),
    );

    _fadeAnimation = CurvedAnimation(
      parent: _fadeAnimationController,
      curve: Curves.easeIn,
    );

    _slideAnimation = Tween(begin: Offset(0, 0), end: Offset(0, -3)).animate(CurvedAnimation(
      parent: _slideAnimationController,
      curve: Curves.easeInOut,
    ));

    _play();
  }

  Future<void> _play() async {
    try {
      await _fadeAnimationController.forward().orCancel;
      await _slideAnimationController.forward().orCancel;
    } on TickerCanceled {
      //Handle if animation was canceled for whatever reason if you need it
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amber,
      body: Center(
        child: SlideTransition(
          position: _slideAnimation,
          child: FadeTransition(
            opacity: _fadeAnimation,
            child: Text(
              'My Life',
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30.0, color: Colors.white70, letterSpacing: 2.0),
            ),
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _fadeAnimationController.dispose();
    _slideAnimationController.dispose();
    super.dispose();
  }
}

更新:

您没有看到填充的变化,因为您有两个错误:

  • 您没有为补间设置动画
  • 您正在使用 symmetric,从两侧添加相同的边距。

要解决补间问题,您需要添加如下内容:

tween = Tween(begin: 400, end: 200).animate(animationController);

要解决填充问题,您可以使用 only,仅在一侧应用 填充

padding: EdgeInsets.only(top: tween)