属性动画(PropertyAnimation)的完全解析

来源:互联网 发布:门窗设计软件 编辑:程序博客网 时间:2024/05/16 01:37

前言

从补间动画、帧动画到属性动画,动画效果越来越丰富、越来越完善。

补间动画(Tween Animation)

a、渐变动画支持的类型:平移(Translate)、旋转(Rotate)、缩放(Scale)、透明度(Alpha)

b、只是显示位置的变动,View的实际位置并没有改变,当View移动之后但点击事件只有在原处才能进行响应

c、组合使用非常的复杂

帧动画(Frame Animation)

a、用于生成连续的Gif效果图

b、DrawableAnimation指此动画

属性动画(Property Animation)

a、支持对所有的View能更新的属性动画(需要属性的set和get方法)

b、更改的是View实际的属性,所以点击事件是在动画结束的最终位置

c、Android3.0(API11),3.0之前可以使用第三方开源库nineoldandroids.jar进行支持


Part 1、Property Animation的使用

最简单的使用

iv.setRotationX(180);
但是不能设置延时,效果很简单

接下来便是属性动画基本使用

                ObjectAnimator animator = ObjectAnimator.ofFloat(v, "translationX", 0, 400);                animator.setDuration(500);                animator.start();
就这样一个简易的平移动画就完成了,除此之外你也可以使用其它的方法来实现相同的效果

            ObjectAnimator animator = ObjectAnimator.ofFloat(v, "andly", 0, 400);            animator.setDuration(500);            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator animation) {                    //animation.getAnimatedFraction();//百分比                    //得到duration时间内 values当中的某一个中间值。                    float value = (float) animation.getAnimatedValue();                    //animation.getCurrentPlayTime();                    iv.setTranslationX(value);                }            });            animator.start();
这里需要注意的是这里的propertyName为View不存在的属性,即使不存在该属性也会在500毫秒之内从0到400进行变化,只需要监听updateListener在里面对View实现动画即可。与上相同的代码
            ValueAnimator animator = ValueAnimator.ofFloat(0,400);            animator.setDuration(500);            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator animation) {                    iv.setTranslationX((Float) animation.getAnimatedValue());                }            });            animator.start();
最后一种方法
                PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX", 0, 300, 500);                PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("rotationX", 0, 180, 360);                ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(v, pvh1,pvh2);                animator.setDuration(500);                animator.start();
tips:

1、...Values使用的是三个参数  0-300  300-500每段所用的时间为250

2、PropertyValueHolder可以为其加入关键帧(时间/值对组成),允许您在动画的特定时间定义特定状态。 每个关键帧也可以有自己的插值器,以控制动画在上一个关键帧的时间和该关键帧的时间之间的间隔中的行为。

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);Keyframe kf2 = Keyframe.ofFloat(1f, 0f);PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)rotationAnim.setDuration(5000ms);
最后来实现一个抛物线的属性动画
                ValueAnimator animator = new ValueAnimator();                animator.setDuration(1000);                animator.setObjectValues(new PointF(0,0));//确定ValueAnimator使用的类型                animator.setEvaluator(new TypeEvaluator<PointF>() {                    @Override                    public PointF evaluate(float fraction, PointF startValue, PointF endValue) {                        PointF pointF = new PointF();                        pointF.x = 20 * (fraction * 10);//20为速度  10为总共的时间                        pointF.y = 0.5f * 9.8f * (fraction * 10) * (fraction * 10);                        return pointF;                    }                });                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                    @Override                    public void onAnimationUpdate(ValueAnimator animation) {                        PointF pointF = (PointF) animation.getAnimatedValue();                        iv.setX(pointF.x);                        iv.setY(pointF.y);                    }                });                animator.start();

    

当然你也可以为你的动画添加加速器


Part 2、浪漫刷礼物效果

效果~


分析:这里心图片动画有两种:1、自身的显示动画(缩放、透明度效果)2、路线(贝塞尔曲线)3、消失动画

自身动画

    private AnimatorSet getBasicAnimation(ImageView iv) {        ObjectAnimator ap = ObjectAnimator.ofFloat(iv, "alpha", 0.1f, 1.0f);        ObjectAnimator scaleX = ObjectAnimator.ofFloat(iv, "scaleX", 0.1f, 1.0f);        ObjectAnimator scaleY = ObjectAnimator.ofFloat(iv, "scaleY", 0.1f, 1.0f);        AnimatorSet set = new AnimatorSet();        set.playTogether(ap, scaleX, scaleY);        set.setTarget(iv);        return set;    }
路线动画

    private ValueAnimator getIVAnimator(final ImageView iv) {        final PointF point0 = new PointF(0, height);        PointF point1 = new PointF(random.nextInt(width), random.nextInt(height));        PointF point2 = new PointF(random.nextInt(width), random.nextInt(height));        PointF point3 = new PointF(random.nextInt(width), 0);        MyTypeEvaluator myEvaluator = new MyTypeEvaluator(point1, point2);        ValueAnimator valueAnimator = ValueAnimator.ofObject(myEvaluator, point0, point3);        valueAnimator.setTarget(iv);        valueAnimator.setDuration(3000);        valueAnimator.setInterpolator(interpolators[random.nextInt(interpolators.length)]);        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                PointF pointF = (PointF) animation.getAnimatedValue();                iv.setX(pointF.x);                iv.setY(pointF.y);                iv.setAlpha(1 - animation.getAnimatedFraction());            }        });        return valueAnimator;    }
这里用到了自定义插值器来定义计算规则,让在在AnimationUpdate方法里面对ImageView进行位置的改变并且透明度的改变

public class MyTypeEvaluator implements TypeEvaluator<PointF> {    private PointF point1;    private PointF point2;    public MyTypeEvaluator(PointF point1, PointF point2) {        this.point1 = point1;        this.point2 = point2;    }    @Override    public PointF evaluate(float t, PointF point0, PointF point3) {        PointF point = new PointF();        point.x = point0.x * (1 - t) * (1 - t) * (1 - t) + point1.x * t * (1 - t) * (1 - t) + point2.x * t * t * (1 - t) + point3.x * t * t * t;        point.y = point0.y * (1 - t) * (1 - t) * (1 - t) + point1.y * t * (1 - t) * (1 - t) + point2.y * t * t * (1 - t) + point3.y * t * t * t;        return point;    }}
这里的evaluate是根据贝塞尔曲线的三次曲线方程来写的




0 0
原创粉丝点击