Android属性动画1-----属性动画的简单使用

在Android开发过程中,最原始的2种动画分别为补间动画和帧动画,两者存在的弊端都非常明显,补间动画只能由肉眼观察到动画,然而却不能响应点击事件,因为容器并没有移动;帧动画因为需要大量的图片做基础,对内存也是非常大的消耗,因此在项目中都会尽量避免使用帧动画。

在API 3.0之后,出现了第3种动画属性动画,也是当前使用频率最高的动画类型,大部分App中的动画特效均为属性动画制作。

1、属性动画

属性动画解决了补间动画的弊端,容器随着动画的移动而移动,对于任意对象均可设置动画,常用的动画有ValueAnimator(值动画)、ObjectAnimator (对象动画),下面的都是这两个重要动画的辅助工具:PropertyValueHolder(多个动画同时执行)、AnimationSet(集合动画)、Interpolator (插值器)、TypeEvaluator(估值器)

(1)ObjectAnimator

//对象动画,但不局限于对象
                ObjectAnimator oa = ObjectAnimator.ofFloat(iv_animation,
                        "alpha",1.0f,0.4f);
                oa.setDuration(3000);
                //开启动画
                oa.start();

(2)ValueAnimator

这是Android属性动画中最核心的类,通过设置数值完成平滑的匀速移动,通过设置监听得到当前的值,设置给View完成动画的移动。

//值动画
                ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100);
                valueAnimator.setDuration(3000);

                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        //获取当前动态变化的值
                        int location = (int) animation.getAnimatedValue();
                        iv_animation.setX(location);
                        iv_animation.setY(location);
                    }
                });
                //启动动画
                valueAnimator.start();

通过设置addUpdateListener监听,可以使用getAnimatedValue获取当前移动的距离,设置View的x,y坐标。

除了上述的API之外,还可以设置重复的次数。

 //设置重复的次数
                valueAnimator.setRepeatCount(2);
                valueAnimator.setRepeatCount(ValueAnimator.RESTART);

(3)PropertyValueHolder

//多个动画同时进行
                PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.3f);
                PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.5f);
                PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.5f);

                ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(iv_animation,holder1,holder2,holder3);
                objectAnimator.setDuration(3000);
                objectAnimator.start();

PropertyValueHolder是多个动画同时运行,是通过ObjectAnimatorofPropertyValuesHolder来实现,例如上例中,分别3个动画为:清晰度、X轴缩放为原来的一半、Y轴缩放为原来的一半。

和AnimationSet有什么区别呢?
AnimationSet同样也是集合动画,但是AnimationSet更加灵活,可以一起执行,也可以是顺序执行,执行完一个动画之后 就会执行下一个动画。

(4)AnimationSet

 ObjectAnimator o1 = ObjectAnimator.ofFloat(iv_animation,"translationX",0f,500f);
                ObjectAnimator o2 = ObjectAnimator.ofFloat(iv_animation,"alpha",1.0f,0.5f);
                ObjectAnimator o3 = ObjectAnimator.ofFloat(iv_animation,"scaleX",1.0f,1.5f);

                AnimatorSet set = new AnimatorSet();
                set.setDuration(3000);
                set.playSequentially(o1,o2,o3);
                set.start();

playSequentially就是按顺序执行,会依次执行完3个动画。

//链式调用
                set.play(o3).with(o2).after(o1);
                set.play(o3).with(o2).before(o1);

通过链式调用,控制动画的播放顺序,在上述的链式中,就是设计的在o1动画完成之后(或者之前before),o2和o3会一起执行。

 set.playTogether(o1,o2,o3);

使用playTogether就是实现了PropertyValueHolder的功能,能够实现多个动画的同时执行。

(5)TypeEvaluator(估值器)

对于ValueAnimationObjectAnimation来说,他们的状态变化是匀速的,等值地变化,因此对于想要实现加速度的效果,例如自由落体,单纯地使用这2种属性动画就比较难了,因此可以使用估值器来完成。

估值器可以自定义动画的变换规则,也可以改变运行轨迹,实现特殊的动画效果

//设计平抛效果
                ValueAnimator animator = new ValueAnimator();
                animator.setDuration(3000);
                //初始坐标为0 0
                animator.setObjectValues(new PointF(0,0));
                final PointF pointF = new PointF();

                animator.setEvaluator(new TypeEvaluator() {
                    @Override
                    public Object evaluate(float fraction, Object startValue, Object endValue) {
                        pointF.x = 100f * (fraction * 5);
                        pointF.y = 0.5f * 98f * (fraction*5)*(fraction * 5);
                        return pointF;
                    }
                });

                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        //获取估值器中自定义好的对象
                        PointF location = (PointF) animation.getAnimatedValue();
                        iv_animation.setX(location.x);
                        iv_animation.setY(location.y);
                    }
                });

                animator.start();

在使用ValueAnimator时,调用addUpdateListener,内部其实也有一个估值器,但是这个估值器是匀速的,通过getAnimatedValue可以得到其中的值,但是要想实现自由落体的效果,匀速的估值器是不可能实现的,平抛水平方向匀速,竖直方向自由落体,因此需要通过setEvaluator更改估值器,在x和y轴设置,返回Object对象,在getAnimatedValue中就可以得到这个PointF

(6)Interpolator 插值器

其实插值器和估值器是类似的,唯一的区别在于,估值器的算法需要自己编写,而插值器的算法是由API提供的,大概分为9种。

 				ValueAnimator v1 = new ValueAnimator();
                v1.setDuration(3000);
                v1.setObjectValues(new PointF(0,0));
                final PointF point = new PointF();

                v1.setEvaluator(new TypeEvaluator() {
                    @Override
                    public Object evaluate(float fraction, Object startValue, Object endValue) {
                        point.x = 100f * (fraction * 5);
                        point.y = 0.5f * 98f * (fraction*5)*(fraction * 5);
                        return point;
                    }
                });

                v1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        //获取估值器中自定义好的对象
                        PointF location = (PointF) animation.getAnimatedValue();
                        iv_animation.setX(location.x);
                        iv_animation.setY(location.y);
                    }
                });
                //加速度插值器
                v1.setInterpolator(new AccelerateInterpolator(10));

                v1.start();

AccelerateInterpolator:加速插值器,公式: y=t^(2f) (加速度参数. f越大,起始速度越慢,但是速度越来越快;刚开始速度很慢,但是瞬间就下落。)

v1.setInterpolator(new DecelerateInterpolator(5));

DecelerateInterpolator:减速插值器公式: y=1-(1-t)^(2f) (描述: 加速度参数. f越大,起始速度越快,但是速度越来越慢)

v1.setInterpolator(new AccelerateDecelerateInterpolator());

AccelerateDecelerateInterpolator:先加速后减速

v1.setInterpolator(new AnticipateInterpolator(tension:8));

AnticipateInterpolator:张力值,tension值越大,偏移量就越大,而且速度越快。

v1.setInterpolator(new AnticipateOvershootInterpolator(2,3));
public AnticipateOvershootInterpolator() {
        mTension = 2.0f * 1.5f;
    }
public AnticipateOvershootInterpolator(float tension, float extraTension) {
        mTension = tension * extraTension;
    }

AnticipateOvershootInterpolator:张力插值器,类似于抛物线似的,tension和extraTension默认值是2和1.5,值越大,偏移量就越大,速度就越快。

v1.setInterpolator(new BounceInterpolator());

BounceInterpolator:弹跳插值器

  v1.setInterpolator(new CycleInterpolator(2));

CycleInterpolator:周期插值器,可以设置动画重复的时间周期,类似于repeat

v1.setInterpolator(new LinearInterpolator());

LinearInterpolator:匀速插值器,这个会屏蔽之前自定义的估值器,而是匀速的完成平抛。

以上就是属性动画中最重要的动画及辅助器,最核心的ValueAnimator类,将会配合估值器和插值器实现多种类型的动画,包括现在的App中,尤其是直播类的App中,观众在发送礼物时,屏幕上会出现该礼物的动画效果,这就涉及到了属性动画的使用,在之后的章节中,将会详细介绍属性动画的高级使用,打造一个动画框架。

你可能感兴趣的:(Android属性动画1-----属性动画的简单使用)