首页 > 代码库 > Android动画——属性动画

Android动画——属性动画

一、概述

  Android在API11后加入的新特性,主要通过对对象的属性动态改变实现动画效果,也因此大大扩展了作用对象,并且由于直接对属性进行变换,动画效果也更丰富。主要有ValueAnimator、ObjectAninmator、AnimatorSet等概念。

二、属性动画的分类及使用

  1、ObjectAnimator 继承自ValueAnimator,使用举例如下

ObjectAnimator.ofFloat(button,"translationY",100).setDuration(2000).start();

    传入作用对象,属性名称、变化值,并可设置相关参数,最后调用start开始动画。

  2、ValueAnimator 可以改变任意一个属性,但没有作用对象,只产生属性值的变化,使用时可以为其添加监听。属性动画的监听接口主要有两个,AnimateUpdateListener和AnimateListener。其中前者为逐帧监听,后者则是监听不同的四个状态,与View动画的监听类似。

     在使用该对象时,可以在AnimateUpdateListener的监听方法中逐帧获得Animator的属性值,由此动态的设置动画的作用对象实现动画效果。代码如下:

        ValueAnimator colorAnim = ObjectAnimator.ofInt(this,"backgroundColor",0xFFFF8080,0xFF8080FF);
        colorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int colorValue = http://www.mamicode.com/(int) animation.getAnimatedValue();
                button.setBackgroundColor(colorValue);
            }
        });
        colorAnim.setDuration(3000);
        colorAnim.setEvaluator(new ArgbEvaluator());
        colorAnim.setRepeatCount(ValueAnimator.INFINITE);
        colorAnim.setRepeatMode(ValueAnimator.REVERSE);
        colorAnim.start();

    由此可对任意属性进行动画,除此之外还有两种不同的方法实现任意属性动画。

    其中getAnimatedValue是获得当前进度值,与创建对象时传入的始末值有关,除此之外还可以利用Evaluator(估算器)计算得到所需的属性值,代码如下

                float fraction = animation.getAnimatedFraction();

                target.getLayoutParams().width = intEvaluator.evaluate(fraction,start,end);
                target.requestLayout();

    通过获得getAnimatedFraction获得fraction,再利用IntEvaluator对象传入fraction、start(属性初值),end(属性末值)计算得到当前属性值,由此也可以使用自定义的Evaluator来计算属性值得到更灵活的动画效果。

    requestLayout是当View确定自身已不适合现有区域时,调用该方法重新完成measure和layout过程以刷新位置。

  3、AnimatorSet 动画集合,顾名思义,可设置多个动画效果,使用很简单,如下

 AnimatorSet set = new AnimatorSet();
        set.playTogether(ObjectAnimator.ofFloat(/*设置动画效果及对象*/),
                ObjectAnimator.ofFloat(/*设置动画效果及对象*/),
                ObjectAnimator.ofInt(/*设置动画效果及对象*/));
        set.setDuration(5000).start();

  除此之外,属性动画也可通过XML定义。简单介绍使用的标签及属性。

  属性动画定义在res/animator 目录下。

  标签<set> 属性 ordering(together/squentially)动画集合中的动画的播放顺序。

  标签<objectAnimator> 属性 propertyName 属性名称、durantion 持续时间、valueFrom、valueTo、startOffset (int)延迟时间,repeatCount 重复次数、repeatMode(repeat/reverse)重复模式、valueType(intType/floatType)颜色属性不需指定。

  标签<animator> 与<objectAnimator>类似,无propertyName属性。

  定义完成后通过以下代码使用属性动画

    AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this,R.anim.animation_test);
        set.setTarget(mButton);
        set.start();

  在实际开发中,由于XML定义的方式无法获得属性的初始值,所以一般采用代码的方式使用属性动画。

三、插值器Interpolator和估值器Evaluator

  在属性动画中,属性随时间的变化由插值器和估算器共同决定。

  1、Interpolator 与View动画中的类似。在属性动画中,Interpolator返回的是属性的改变比例,参数为时间的变化比例。如时间流逝50%时,返回此时属性的变化比例。

  2、Evaluator 内部的evaluate方法接受三个参数,fraction、start、end,根据三者计算得到属性值,其中fraction即属性值的变化比例。

  自定义插值器实现Interpolator或者TimeInterpolator,自定义估算器则实现TypeEvaluator,如果是对其他类型(除int、float、Color外)做动画,则必须要自定义类型估算算法。

四、对任意属性做动画

  属性动画要求动画对象具有属性的get和set方法,其中get方法用于获取属性的起始值,set方法则用于动画执行过程中动态的对属性进行赋值。所以当View无法提供这两个方法或者提供的方法无法对需要的属性进行设置(如Button的setWidth方法)时,就不可以直接使用属性动画(ObjectAnimator)。

  未解决上述问题共有三种方法

  1、为对象添加get和set方法,该方法对于系统提供的View来说无法实现。

  2、用一个类包装原始对象,间接为其提供get和set方法,步骤如下    

    //包装类,为View提供自定义的get和set方法
    private static class ViewWrapper{
        private View target ;

        ViewWrapper(View target){
            this.target = target;
        }

        public int getWidth(){
            return target.getLayoutParams().width;
        }
        public void setWidth(int width){
            target.getLayoutParams().width = width;
            target.requestLayout();
        }
    }

  3、使用ValueAnimator,上文已介绍。

五、属性动画的工作原理

六、注意事项

  1、OOM问题

  2、内存泄露

    对于属性动画中无限循环的动画需在Activity退出时及时的关闭动画,否则会因Activity无法释放而造成内存泄漏

  3、兼容性问题

  4、不要使用px

  5、动画元素交互

    在API11之后,属性动画的效果是可以真实改变View的位置的,而View则只改变影响,所以事件响应会有问题。

  6、View动画的问题

    由于View动画是对View的影像进行操作,所以有时候会出现动画完成后View无法隐藏的情况,此时只要调用clearAnimation清除动画效果即可。

  7、硬件加速

    为了系统顺畅,动画效果建议开启硬件加速。

 

Android动画——属性动画