【问题标题】:FadeTransition and AnimatedOpacity are not in sync with each otherFadeTransition 和 AnimatedOpacity 彼此不同步
【发布时间】:2020-10-30 03:23:57
【问题描述】:

最少的可重现代码:

static const Duration _duration = Duration(seconds: 5);
static const Curve _curve = Curves.fastOutSlowIn;
AnimationController _controller;
bool _flag = false;

@override
void initState() {
  super.initState();
  _controller = AnimationController(vsync: this, duration: _duration);
}

@override
Widget build(BuildContext context) {
  final box = Container(color: Colors.orange, width: 100, height: 100);
  return Scaffold(
    body: Column(
      children: [
        FadeTransition(
          opacity: CurvedAnimation(parent: _controller, curve: _curve),
          child: box,
        ),
        SizedBox(height: 20),
        AnimatedOpacity(
          curve: _curve,
          duration: _duration,
          opacity: _flag ? 1 : 0,
          child: box,
        ),
        SizedBox(height: 20),
        RaisedButton(
          onPressed: () {
            setState(() {
              _flag = !_flag;
              if (_flag) {
                _controller.forward();
              } else {
                _controller.reverse();
              }
            });
          },
          child: Text(_flag ? 'Hide' : 'Show'),
        ),
      ],
    ),
  );
}

输出:

如您所见,两个动画彼此不同步。我对FadeTransitionAnimatedOpacity 使用相同的CurveDuration。但是,如果您删除 curve,动画会同步。那么,我在这里做错了什么?

【问题讨论】:

    标签: flutter flutter-animation


    【解决方案1】:

    调用 _controller.reverse() 时,FadeTransition 使用反转曲线,但 AnimatedOpacity 使用相同曲线。您可以添加 FlippedCurve 小部件来修复它。

    而你没有等到结束就停止动画,controller.reverse 将开始从停止点向相反方向移动。

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage>
        with SingleTickerProviderStateMixin {
      static const Duration _duration = Duration(seconds: 5);
      static const Curve _curve = Curves.fastOutSlowIn;
    
      AnimationController _controller;
      bool isShowing = false;
    
      @override
      void initState() {
        super.initState();
        _controller = AnimationController(vsync: this, duration: _duration);
      }
    
      @override
      Widget build(BuildContext context) {
        final box = Container(color: Colors.orange, width: 100, height: 100);
        return Scaffold(
          backgroundColor: Colors.black,
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                FadeTransition(
                  opacity: CurvedAnimation(parent: _controller, curve: _curve),
                  child: box,
                ),
                SizedBox(height: 20),
                AnimatedOpacity(
                  curve: isShowing ? _curve : FlippedCurve(_curve),
                  duration: _duration,
                  opacity: isShowing ? 1 : 0,
                  child: box,
                ),
                SizedBox(height: 20),
                RaisedButton(
                  onPressed: () {
                    setState(() {
                      if (isShowing) {
                        _controller.reverse();
                      } else {
                        _controller.forward();
                      }
                      isShowing = !isShowing;
                    });
                  },
                  child: Text(isShowing ? 'Hide' : 'Show'),
                ),
                AnimatedBuilder(
                    builder: (_, __) {
                      return Text(
                        _controller.value.toString(),
                        style: TextStyle(
                          color: Colors.white,
                        ),
                      );
                    },
                    animation: _controller)
              ],
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 感谢您给我一个想法 (+1) 。我实际上忘记添加reverseCurve 参数。这解决了我的问题。
    【解决方案2】:

    我错过了reverseCurve 参数。

    FadeTransition(
      opacity: CurvedAnimation(
        parent: _controller,
        curve: _curve,
        reverseCurve: _curve, // Solved the problem. 
      ),
      child: box,
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-07
      • 2013-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多