Flutter淡入/淡出动画在一起

9
在这个简单的示例代码中,我想同时实现淡入和淡出动画,但在这段代码中只有淡入生效而reverse没有生效,我该怎么做才能让它们一起生效?
import 'package:flutter/material.dart';

void main()=>runApp(MaterialApp(home: FadeTransitionSample(),));
class FadeTransitionSample extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _Fade();
}

class _Fade extends State<FadeTransitionSample> with TickerProviderStateMixin {
  AnimationController animation;
  Animation<double> _fadeInFadeOut;

  @override
  void initState() {
    super.initState();
    animation = AnimationController(vsync: this, duration: Duration(seconds: 3),);
    _fadeInFadeOut = Tween<double>(begin: 0.0, end: 0.1).animate(animation);

    animation.addListener((){
      if(animation.isCompleted){
        animation.reverse();
      }else{
        animation.forward();
      }
    });
    animation.repeat();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: FadeTransition(
            opacity: animation,
            child: Container(
              color: Colors.green,
              width: 100,
              height: 100,
            ),
          ),
        ),
      ),
    );
  }
}
2个回答

21

好的,我假设您想在容器上实现淡入淡出动画。

有几个需要更改的地方:

  1. FadeTransition类不应该使用opacity作为动画,而是应该使用_fadeInFadeOut变量。
  2. 当您调用animation.forward()时,动画开始播放,而不是animation.repeat()(在您的情况下,您还需要反转动画,始终从animation.forward()调用开始)。

请确保使用addStatusListener()方法而不是addListener(),因为这样可以更好地控制状态。

将所有这些内容整合起来,下面是使您的动画正常工作的代码:

import 'package:flutter/material.dart';

void main()=>runApp(MaterialApp(home: FadeTransitionSample(),));
class FadeTransitionSample extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _Fade();
}

class _Fade extends State<FadeTransitionSample> with TickerProviderStateMixin {
  AnimationController animation;
  Animation<double> _fadeInFadeOut;

  @override
  void initState() {
    super.initState();
    animation = AnimationController(vsync: this, duration: Duration(seconds: 3),);
    _fadeInFadeOut = Tween<double>(begin: 0.0, end: 0.5).animate(animation);

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: FadeTransition(
            opacity: _fadeInFadeOut,
            child: Container(
              color: Colors.green,
              width: 100,
              height: 100,
            ),
          ),
        ),
      ),
    );
  }
}

谢谢。我该如何设置前进和后退之间的延迟? - DolDurma
2
目前,FadeIn和FadeOut的延迟时间相同。如果您想为两个操作设置不同的持续时间,则必须创建单独的动画并使用它们。不能使用简单的反转方法来实现。还有其他调用,如animateTo()和animateBack(),您可以利用它们。 - baradwaj

4

选项 #1

这是一个简单、直接且代码量少的解决方案。其思路是将 FadeOut 嵌套在 FadeIn 中,并将 FadeOut 的延迟时间设定为大于 FadeIn 的持续时间。只需复制并粘贴以下代码,然后将 Image.asset 小部件更改为您想要淡入/淡出的任何内容即可。

1- 添加 此软件包

2- 在您的页面中导入它:import 'package:animate_do/animate_do.dart';

3- 添加以下小部件:

Widget _animateLogo() {
  return Container(
    child: FadeIn(
        animate: true,
        duration: Duration(seconds: 2),

        child: FadeOut(
          animate: true,
          delay: Duration(seconds: 2),
          duration: Duration(seconds: 1),

          // Just change the Image.asset widget to anything you want to fade in/out:
          child: Image.asset(
            "assets/images/logo.png",
            height: 150,
            width: 150,
            fit: BoxFit.contain,
          ), //Image.asset

        ) // FadeOut
    ),
  );
}

选项 #2:

使用带有setState的本地类AnimatedOpacity

// 1- Declare
bool _shouldFade = false;

// 2- Animation fucntion
Widget _animateLogo() {
  return AnimatedOpacity(
    duration: Duration(milliseconds: 200),
    opacity: _shouldFade ? 1 : 0,
    child: Container(
      // Whatever you want to fadein fadeout
    ),
  );
}

// 3- Animate whenever needed
setState(() {
  // Fade in
  _shouldFade = true;
});

// Fadeout after 3 seconds
Future.delayed(
  Duration(seconds: 3),
  () => setState(() {
        _shouldFade = false;
  }),
);

你必须在你的回答中提供更多细节。Flutter 中没有 FadeIn/Out 小部件。 - Pedro Massango
我更新了答案并添加了更多细节,感谢您的注意! - Osama Remlawi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接