欢迎来到皮皮网网首页

【松鼠大战源码】【虚幻2.5源码】【javasaas系统源码】AnimatorSet源码分析

来源:nginx源码问题 时间:2024-11-25 23:53:04

1.android之animator 和animation 的区别
2.animation和animator的区别

AnimatorSet源码分析

android之animator 和animation 的区别

       ä¸€ã€ 前言

       Animator框架是Android 4.0中新添加的一个动画框架,和之前的Animation框架相比,Animator可以进行更多和更精细化的动画控制,而且比之前更简单和更高效。在4.0源码中随处都可以看到Animator的使用。

       äºŒã€ Animation和Animator比较

       å¦‚下图,是Animation和Animator两个类继承图的对比。

       C:Object C:Object

        C:Animation C:Animator

        C:AlphaAnimation C:AnimatorSet

        C:AnimationSet C:ValueAnimator

        C:DummyAnimation C:ObjectAnimator

        C:Rotate3dAnimation C:TimeAnbimator

        C:RotateAniamtion

        C:ScaleAnimation

        C:TranslateAnimation

       Animation框架定义了透明度,旋转,缩放和位移几种常见的动画,而且控制的是一个整个View动画,实现原理是每次绘制视图时View所在的ViewGroup中的drawChild函数获取该View的Animation的Transformation值,然后调用canvas.concat(transformToApply.getMatrix()),通过矩阵运算完成动画帧,如果动画没有完成,继续调用invalidate()函数,启动下次绘制来驱动动画,动画过程中的帧之间间隙时间是绘制函数所消耗的时间,可能会导致动画消耗比较多的CPU资源。

       åœ¨Animator框架中使用最多的是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进行更精细化控制,只控制一个对象的一个属性值,多个ObjectAnimator组合到AnimatorSet形成一个动画。而且ObjectAnimator能够自动驱动,可以调用setFrameDelay(longframeDelay)设置动画帧之间的间隙时间,调整帧率,减少动画过程中频繁绘制界面,而在不影响动画效果的前提下减少CPU资源消耗。

       ä¸‰ã€ 关键接口介绍

       1. ObjectAnimator介绍

       Animator框架封装得比较完美,对外提供的接口非常简单,创建一个ObjectAnimator只需通过如下图所示的静态工厂类直接返回一个ObjectAnimator对象。传的参数包括一个对象和对象的属性名字,但这个属性必须有get和set函数,内部会通过java反射机制来调用set函数修改对象属性值。还包括属性的初始值,最终值,还可以调用setInterpolator设置曲线函数。

       2. AnimatorSet介绍

       AnimatorSet主要是组合多个AnimatorSet和ObjectAnimator形成一个动画,并可以控制动画的播放顺序,其中还有个辅助类通过调用play函数获得。

       3. AnimatorUpdateListner介绍

       é€šè¿‡å®žçŽ°AnimatorUpdateListner,来获得属性值发生变化时的事件,在这个回调中发起重绘屏幕事件。

       å››ã€ 使用实例

       åœ¨Android4.0中的ApiDemo中有个BouncingBalls实例,描述了Animator框架的使用,当点击屏幕时,绘制一个球从点击位置掉到屏幕底部,碰到底部时球有压扁的效果,然后回弹到点击位置再消失。

       ä»£ç å¦‚下:

       ShapeHolder newBall =addBall(event.getX(),码分松鼠大战源码 event.getY());

        // Bouncing animation with squash and stretch

        float startY = newBall.getY();

        float endY = getHeight() - f;

        float h = (float)getHeight();

        float eventY = event.getY();

        int duration = (int)( * ((h - eventY)/h));

        ValueAnimator bounceAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY);

        bounceAnim.setDuration(duration);

        bounceAnim.setInterpolator(new AccelerateInterpolator());

        ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(newBall, "x", newBall.getX(),

        newBall.getX() - f);

        squashAnim1.setDuration(duration/4);

        squashAnim1.setRepeatCount(1);

        squashAnim1.setRepeatMode(ValueAnimator.REVERSE);

        squashAnim1.setInterpolator(new DecelerateInterpolator());

        ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(newBall, "width", newBall.getWidth(),

        newBall.getWidth() + );

        squashAnim2.setDuration(duration/4);

        squashAnim2.setRepeatCount(1);

        squashAnim2.setRepeatMode(ValueAnimator.REVERSE);

        squashAnim2.setInterpolator(new DecelerateInterpolator());

        ValueAnimator stretchAnim1 = ObjectAnimator.ofFloat(newBall, "y", endY,

        endY + f);

        stretchAnim1.setDuration(duration/4);

        stretchAnim1.setRepeatCount(1);

        stretchAnim1.setInterpolator(new DecelerateInterpolator());

        stretchAnim1.setRepeatMode(ValueAnimator.REVERSE);

        ValueAnimator stretchAnim2 = ObjectAnimator.ofFloat(newBall, "height",

        newBall.getHeight(),newBall.getHeight() - );

        stretchAnim2.setDuration(duration/4);

        stretchAnim2.setRepeatCount(1);

        stretchAnim2.setInterpolator(new DecelerateInterpolator());

        stretchAnim2.setRepeatMode(ValueAnimator.REVERSE);

        ValueAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y", endY,

        startY);

        bounceBackAnim.setDuration(duration);

        bounceBackAnim.setInterpolator(newDecelerateInterpolator());

        // Sequence the down/squash&stretch/upanimations

        AnimatorSet bouncer = new AnimatorSet();

        bouncer.play(bounceAnim).before(squashAnim1);

        bouncer.play(squashAnim1).with(squashAnim2);

        bouncer.play(squashAnim1).with(stretchAnim1);

        bouncer.play(squashAnim1).with(stretchAnim2);

        bouncer.play(bounceBackAnim).after(stretchAnim2);

        // Fading animation - remove the ball when theanimation is done

        ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);

        fadeAnim.setDuration();

        fadeAnim.addListener(new AnimatorListenerAdapter() {

        @Override

        public void onAnimationEnd(Animatoranimation) {

        balls.remove(((ObjectAnimator)animation).getTarget());

        }

        });

        // Sequence the two animations to play oneafter the other

        AnimatorSet animatorSet = new AnimatorSet();

        animatorSet.play(bouncer).before(fadeAnim);

        // Start the animation

        animatorSet.start();

animation和animator的区别

       ä¸€ã€ 前言

       Animator框架是Android 4.0中新添加的一个动画框架,和之前的Animation框架相比,Animator可以进行更多和更精细化的动画控制,而且比之前更简单和更高效。在4.0源码中随处都可以看到Animator的使用。

       äºŒã€ Animation和Animator比较

       å¦‚下图,是Animation和Animator两个类继承图的对比。

       C:Object C:Object

        C:Animation C:Animator

        C:AlphaAnimation C:AnimatorSet

        C:AnimationSet C:ValueAnimator

        C:DummyAnimation C:ObjectAnimator

        C:Rotate3dAnimation C:TimeAnbimator

        C:RotateAniamtion

        C:ScaleAnimation

        C:TranslateAnimation

       Animation框架定义了透明度,旋转,缩放和位移几种常见的动画,而且控制的是一个整个View动画,实现原理是每次绘制视图时View所在的ViewGroup中的drawChild函数获取该View的Animation的Transformation值,然后调用canvas.concat(transformToApply.getMatrix()),通过矩阵运算完成动画帧,如果动画没有完成,继续调用invalidate()函数,启动下次绘制来驱动动画,动画过程中的帧之间间隙时间是绘制函数所消耗的时间,可能会导致动画消耗比较多的CPU资源。

       åœ¨Animator框架中使用最多的是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进行更精细化控制,只控制一个对象的一个属性值,多个ObjectAnimator组合到AnimatorSet形成一个动画。而且ObjectAnimator能够自动驱动,可以调用setFrameDelay(longframeDelay)设置动画帧之间的间隙时间,调整帧率,减少动画过程中频繁绘制界面,而在不影响动画效果的前提下减少CPU资源消耗。

       ä¸‰ã€ 关键接口介绍

       1. ObjectAnimator介绍

       Animator框架封装得比较完美,对外提供的接口非常简单,创建一个ObjectAnimator只需通过如下图所示的静态工厂类直接返回一个ObjectAnimator对象。传的参数包括一个对象和对象的属性名字,但这个属性必须有get和set函数,内部会通过java反射机制来调用set函数修改对象属性值。还包括属性的初始值,最终值,还可以调用setInterpolator设置曲线函数。

       2. AnimatorSet介绍

       AnimatorSet主要是组合多个AnimatorSet和ObjectAnimator形成一个动画,并可以控制动画的播放顺序,其中还有个辅助类通过调用play函数获得。

       3. AnimatorUpdateListner介绍

       é€šè¿‡å®žçŽ°AnimatorUpdateListner,来获得属性值发生变化时的事件,在这个回调中发起重绘屏幕事件。

       å››ã€ 使用实例

       åœ¨Android4.0中的ApiDemo中有个BouncingBalls实例,描述了Animator框架的使用,当点击屏幕时,绘制一个球从点击位置掉到屏幕底部,碰到底部时球有压扁的效果,然后回弹到点击位置再消失。

       ä»£ç å¦‚下:

       ShapeHolder newBall =addBall(event.getX(), event.getY());

        // Bouncing animation with squash and stretch

        float startY = newBall.getY();

        float endY = getHeight() - f;

        float h = (float)getHeight();

        float eventY = event.getY();

        int duration = (int)( * ((h - eventY)/h));

        ValueAnimator bounceAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY);

        bounceAnim.setDuration(duration);

        bounceAnim.setInterpolator(new AccelerateInterpolator());

        ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(newBall, "x", newBall.getX(),

        newBall.getX() - f);

        squashAnim1.setDuration(duration/4);

        squashAnim1.setRepeatCount(1);

        squashAnim1.setRepeatMode(ValueAnimator.REVERSE);

        squashAnim1.setInterpolator(new DecelerateInterpolator());

        ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(newBall, "width", newBall.getWidth(),

        newBall.getWidth() + );

        squashAnim2.setDuration(duration/4);

        squashAnim2.setRepeatCount(1);

        squashAnim2.setRepeatMode(ValueAnimator.REVERSE);

        squashAnim2.setInterpolator(new DecelerateInterpolator());

        ValueAnimator stretchAnim1 = ObjectAnimator.ofFloat(newBall, "y", endY,

        endY + f);

        stretchAnim1.setDuration(duration/4);

        stretchAnim1.setRepeatCount(1);

        stretchAnim1.setInterpolator(new DecelerateInterpolator());

        stretchAnim1.setRepeatMode(ValueAnimator.REVERSE);

        ValueAnimator stretchAnim2 = ObjectAnimator.ofFloat(newBall, "height",

        newBall.getHeight(),newBall.getHeight() - );

        stretchAnim2.setDuration(duration/4);

        stretchAnim2.setRepeatCount(1);

        stretchAnim2.setInterpolator(new DecelerateInterpolator());

        stretchAnim2.setRepeatMode(ValueAnimator.REVERSE);

        ValueAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y", endY,

        startY);

        bounceBackAnim.setDuration(duration);

        bounceBackAnim.setInterpolator(newDecelerateInterpolator());

        // Sequence the down/squash&stretch/upanimations

        AnimatorSet bouncer = new AnimatorSet();

        bouncer.play(bounceAnim).before(squashAnim1);

        bouncer.play(squashAnim1).with(squashAnim2);

        bouncer.play(squashAnim1).with(stretchAnim1);

        bouncer.play(squashAnim1).with(stretchAnim2);

        bouncer.play(bounceBackAnim).after(stretchAnim2);

        // Fading animation - remove the ball when theanimation is done

        ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);

        fadeAnim.setDuration();

        fadeAnim.addListener(new AnimatorListenerAdapter() {

        @Override

        public void onAnimationEnd(Animatoranimation) {

        balls.remove(((ObjectAnimator)animation).getTarget());

        }

        });

        // Sequence the two animations to play oneafter the other

        AnimatorSet animatorSet = new AnimatorSet();

        animatorSet.play(bouncer).before(fadeAnim);

        // Start the animation

        animatorSet.start();