美文网首页Flutter相关android基础知识android性能优化
Flutter Animations动画效果合集(全网最全)

Flutter Animations动画效果合集(全网最全)

作者: StevenHu_Sir | 来源:发表于2019-11-30 13:25 被阅读0次
    • CurvedAnimation(曲线动画)
    • Tween(补间动画/伸缩动画)
    • Loading加载动画(ProgressDialog)
    • Fade 渐入淡出动画
    • AnimatedBuilder(曲线动画)
    • StaggerAnimation(交错动画)
    • AnimatedSwitcher(切换动画)

    1.CurvedAnimation(曲线动画)

    效果图

    曲线.gif

    关键代码

    import 'package:flutter/material.dart';
    
    class CurvedAnimationPage extends StatefulWidget {
      CurvedAnimationPage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _CurvedAnimationState createState() => _CurvedAnimationState();
    }
    
    class _CurvedAnimationState extends State<CurvedAnimationPage>
        with SingleTickerProviderStateMixin {
      Animation<double> animation;
      AnimationController controller;
    
      @override
      void initState() {
        super.initState();
        controller = AnimationController(
            duration: const Duration(milliseconds: 2000), vsync: this);
        animation = CurvedAnimation(parent: controller, curve: Curves.bounceIn)
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              controller.reverse();
            } else if (status == AnimationStatus.dismissed) {
              controller.forward();
            }
          });
    
        controller.forward();
      }
    
      dispose() {
        controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedLogo(animation: animation);
      }
    }
    
    class AnimatedLogo extends AnimatedWidget {
      // The Tweens are static because they don't change.
      static final _opacityTween = Tween<double>(begin: 0.1, end: 1.0);
      static final _sizeTween = Tween<double>(begin: 0.0, end: 300.0);
    
      AnimatedLogo({Key key, Animation<double> animation})
          : super(key: key, listenable: animation);
    
      Widget build(BuildContext context) {
        final Animation<double> animation = listenable;
        return Scaffold(
            appBar: AppBar(
              title: Text("曲线动画"),
            ),
            body: Center(
              child: Opacity(
                  opacity: _opacityTween.evaluate(animation),
                  child: Container(
                    margin: EdgeInsets.symmetric(vertical: 10.0),
                    height: _sizeTween.evaluate(animation),
                    width: _sizeTween.evaluate(animation),
                    child: FlutterLogo(),
                  )),
            ));
      }
    }
    
    • parent参数传入一个Animation对象,比如AnimationController
    • curve传入传入的就是动画曲线的具体实现,Curves类中已经帮我们默认实现了很多常用的动画曲线,比如减速运动Curves.decelerate

    Curves曲线 动画过程
    linear 匀速的
    decelerate 匀减速
    ease 开始加速,后面减速
    easeIn 开始慢,后面快
    easeOut 开始快,后面慢
    easeInOut 开始慢,然后加速,最后再减速

    2.Tween(补间动画/伸缩动画)

    效果图

    补间动画.gif

    在补间动画中,定义了开始点和结束点、时间线以及定义转换时间和速度的曲线。然后由框架计算如何从开始点过渡到结束点。
    Animation 对象,是 Flutter 动画库中的核心类,插入用于引导动画的值。
    Animation 对象知道当前动画的状态(如:动画是否开始,停止,前进或者后退),但对屏幕上显示的内容一无所知。
    AnimationController 对象管理着 Animation。
    CurvedAnimation 将动画定义成非线性运动的动画。

    关键代码

    import 'package:flutter/material.dart';
    
    class TweenAnimation extends StatefulWidget {
      TweenAnimation({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _TweenAnimationState createState() => _TweenAnimationState();
    }
    
    class _TweenAnimationState extends State<TweenAnimation>
        with SingleTickerProviderStateMixin {
      Animation<double> animation;
      AnimationController controller;
    
      @override
      void initState() {
        super.initState();
        controller = AnimationController(
            duration: const Duration(milliseconds: 2000), vsync: this);
        animation = Tween(begin: 0.0, end: 300.0).animate(controller)
          ..addListener(() {
            setState(() {
              print(animation.value);
            });
          })
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              controller.reverse();
            } else if (status == AnimationStatus.dismissed) {
              controller.forward();
            }
          });
        controller.forward();
      }
    
      dispose() {
        controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("补间动画"),
            ),
            body: Container(
              margin: EdgeInsets.symmetric(vertical: 10.0),
              height: animation.value,
              width: animation.value,
              child: FlutterLogo(),
            ));
      }
    }
    

    3.Loading加载动画(ProgressDialog)

    效果图

    Loading.gif

    关键代码

    import 'package:flutter/material.dart';
    import 'package:flutter_animations/progress_dialog.dart';
    
    class LoadingPage extends StatefulWidget {
      LoadingPage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _LoadingState createState() => _LoadingState();
    }
    
    class _LoadingState extends State<LoadingPage> {
      bool _loading = false;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("加载动画"),
          ),
          body: ProgressDialog(
            isLoading: _loading,
            message: '正在加载...',
            alpha: 0.35,
            child: Center(
              child: RaisedButton(
                onPressed: () => _onRefresh(),
                child: Text('显示加载动画'),
              ),
            ),
          ),
        );
      }
    
      Future<Null> _onRefresh() async {
        setState(() {
          _loading = !_loading;
        });
        // 模拟耗时操作
        await Future.delayed(Duration(seconds: 5), () {
          setState(() {
            _loading = !_loading;
          });
        });
      }
    }
    

    4.Fade 渐入淡出动画

    效果图

    渐入淡出.gif

    关键代码

    import 'package:flutter/material.dart';
    
    class Fade extends StatefulWidget {
      Fade({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _FadeState createState() => _FadeState();
    }
    
    class _FadeState extends State<Fade> {
      bool _visible = true;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("渐入淡出动画"),
          ),
          body: Center(
            child: AnimatedOpacity(
                opacity: _visible ? 1.0 : 0.0,
                duration: Duration(milliseconds: 500),
                child: FlutterLogo(
                  size: 100.0,
                )),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              setState(() {
                _visible = !_visible;
              });
            },
            tooltip: "Toggole Opacity",
            child: Icon(Icons.flip),
          ),
        );
      }
    }
    

    5.AnimatedBuilder(曲线动画)

    效果图

    AnimatedBuilder.gif
    • 创建动画的widget
    • Key key,
    • @required Listenable animation,
    • @required this.builder,
    • this.child,
    • animation:Animationcontroller //动画
    • child 动画作用的view
    • builder:每次controller值改变都会回到builder 重新生成view

    关键代码

    import 'package:flutter/material.dart';
    
    class AnimatedBuilderPage extends StatefulWidget {
      AnimatedBuilderPage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _AnimatedBuilderState createState() => _AnimatedBuilderState();
    }
    
    class _AnimatedBuilderState extends State<AnimatedBuilderPage>
        with SingleTickerProviderStateMixin {
      Animation<double> animation;
      AnimationController controller;
    
      @override
      void initState() {
        super.initState();
        controller = AnimationController(
            duration: const Duration(milliseconds: 2000), vsync: this);
        final CurvedAnimation curve =
            CurvedAnimation(parent: controller, curve: Curves.bounceIn);
        animation = Tween(begin: 0.0, end: 300.0).animate(curve)
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              controller.reverse();
            } else if (status == AnimationStatus.dismissed) {
              controller.forward();
            }
          });
        controller.forward();
      }
    
      dispose() {
        controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return GrowTransition(child: LogoWidget(), animation: animation);
      }
    }
    
    class LogoWidget extends StatelessWidget {
      build(BuildContext context) {
        return Container(
          margin: EdgeInsets.symmetric(vertical: 10.0),
          child: FlutterLogo(),
        );
      }
    }
    
    class GrowTransition extends StatelessWidget {
      GrowTransition({this.child, this.animation});
    
      final Widget child;
      final Animation<double> animation;
    
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("曲线动画AnimatedBuilder实现"),
          ),
          body: Center(
            child: AnimatedBuilder(
                animation: animation,
                builder: (BuildContext context, Widget child) {
                  return Container(
                      height: animation.value,
                      width: animation.value,
                      child: child);
                },
                child: child),
          ),
        );
      }
    }
    

    6.StaggerAnimation(交错动画)

    交错动画由序列或重叠的动画组成,
    要创建交错动画,使用多个动画对象,
    一个AnimationController控制所有动画。
    每个动画对象在间隔期间指定动画。

    效果图

    StaggerAnimation.gif

    关键代码

    import 'package:flutter/material.dart';
    
    import 'dart:async';
    import 'package:flutter/scheduler.dart' show timeDilation;
    
    class StaggerAnimation extends StatelessWidget {
      StaggerAnimation({Key key, this.controller}):
    
            opacity = Tween<double>(
              begin: 0.0,
              end: 1.0,
            ).animate(
              CurvedAnimation(
                parent: controller,
                curve: Interval(
                  0.0,
                  0.100,
                  curve: Curves.ease,
                ),
              ),
            ),
            width = Tween<double>(
              begin: 50.0,
              end: 150.0,
            ).animate(
              CurvedAnimation(
                parent: controller,
                curve: Interval(
                  0.125,
                  0.250,
                  curve: Curves.ease,
                ),
              ),
            ),
            height = Tween<double>(begin: 50.0, end: 150.0).animate(
              CurvedAnimation(
                parent: controller,
                curve: Interval(
                  0.250,
                  0.375,
                  curve: Curves.ease,
                ),
              ),
            ),
            padding = EdgeInsetsTween(
              begin: const EdgeInsets.only(bottom: 16.0),
              end: const EdgeInsets.only(bottom: 75.0),
            ).animate(
              CurvedAnimation(
                parent: controller,
                curve: Interval(
                  0.250,
                  0.375,
                  curve: Curves.ease,
                ),
              ),
            ),
            borderRadius = BorderRadiusTween(
              begin: BorderRadius.circular(4.0),
              end: BorderRadius.circular(75.0),
            ).animate(
              CurvedAnimation(
                parent: controller,
                curve: Interval(
                  0.375,
                  0.500,
                  curve: Curves.ease,
                ),
              ),
            ),
            color = ColorTween(
              begin: Colors.indigo[100],
              end: Colors.orange[400],
            ).animate(
              CurvedAnimation(
                parent: controller,
                curve: Interval(
                  0.500,
                  0.750,
                  curve: Curves.ease,
                ),
              ),
            ),
            super(key: key);
    
      final Animation<double> controller;
      final Animation<double> opacity;
      final Animation<double> width;
      final Animation<double> height;
      final Animation<EdgeInsets> padding;
      final Animation<BorderRadius> borderRadius;
      final Animation<Color> color;
    
      // This function is called each time the controller "ticks" a new frame.
      // When it runs, all of the animation's values will have been
      // updated to reflect the controller's current value.
      Widget _buildAnimation(BuildContext context, Widget child) {
        return Container(
          padding: padding.value,
          alignment: Alignment.bottomCenter,
          child: Opacity(
            opacity: opacity.value,
            child: Container(
              width: width.value,
              height: height.value,
              decoration: BoxDecoration(
                color: color.value,
                border: Border.all(
                  color: Colors.indigo[300],
                  width: 3.0,
                ),
                borderRadius: borderRadius.value,
              ),
            ),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedBuilder(
          builder: _buildAnimation,
          animation: controller,
        );
      }
    }
    
    class StaggerDemo extends StatefulWidget {
      @override
      _StaggerDemoState createState() => _StaggerDemoState();
    }
    
    class _StaggerDemoState extends State<StaggerDemo>
        with TickerProviderStateMixin {
      AnimationController _controller;
    
      @override
      void initState() {
        super.initState();
    
        _controller = AnimationController(
            duration: const Duration(milliseconds: 2000), vsync: this);
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      Future<void> _playAnimation() async {
        try {
          await _controller.forward().orCancel;
          await _controller.reverse().orCancel;
        } on TickerCanceled {
          // the animation got canceled, probably because we were disposed
        }
      }
    
      @override
      Widget build(BuildContext context) {
        timeDilation = 10.0; // 1.0 is normal animation speed.
        return Scaffold(
          appBar: AppBar(
            title: const Text('Staggered Animation'),
          ),
          body: GestureDetector(
            behavior: HitTestBehavior.opaque,
            onTap: () {
              _playAnimation();
            },
            child: Center(
              child: Container(
                width: 300.0,
                height: 300.0,
                decoration: BoxDecoration(
                  color: Colors.black.withOpacity(0.1),
                  border: Border.all(
                    color: Colors.black.withOpacity(0.5),
                  ),
                ),
                child: StaggerAnimation(controller: _controller.view),
              ),
            ),
          ),
        );
      }
    }
    

    7.AnimatedSwitcher(切换动画)

    实际开发中,我们经常会遇到切换UI元素的场景,比如Tab切换、路由切换。为了增强用户体验,通常在切换时都会指定一个动画,以使切换过程显得平滑。

    效果图

    切换动画.gif

    关键代码

    import 'package:flutter/material.dart';
    
    class AnimatedSwitcherDemo extends StatefulWidget {
      AnimatedSwitcherDemo({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _AnimatedSwitcherState createState() => _AnimatedSwitcherState();
    }
    
    class _AnimatedSwitcherState extends State<AnimatedSwitcherDemo>
        with SingleTickerProviderStateMixin {
      IconData _actionIcon = Icons.favorite_border;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('点击中间的❤️'),
            actions: <Widget>[],
          ),
          body: Center(
            child: AnimatedSwitcher(
              transitionBuilder: (child, anim) {
                return ScaleTransition(child: child, scale: anim);
              },
              duration: Duration(milliseconds: 350),
              child: IconButton(
                iconSize: 100,
                key: ValueKey(_actionIcon),
                icon: Icon(
                  _actionIcon,
                  color: Colors.pink,
                ),
                onPressed: () {
                  setState(
                    () {
                      if (_actionIcon == Icons.favorite_border)
                        _actionIcon = Icons.favorite;
                      else
                        _actionIcon = Icons.favorite_border;
                    },
                  );
                },
              ),
            ),
          ),
        );
      }
    }
    

    相关文章

      网友评论

        本文标题:Flutter Animations动画效果合集(全网最全)

        本文链接:https://www.haomeiwen.com/subject/gwagwctx.html