Android属性动画

  在Animator 框架中,使用最多的就是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进行更加精细的控制,只控制一个对象的一个属性值,尔斯用多个ObjectAnimator组合到AnimatorSet形成一个动画。而且ObjectAnimator能够自动驱动,可以调用setFrameDelay(longframeDelay)设置动画帧之间的见习时间,调整帧率,减少动画过程中频繁绘制界面,而在不影响动画效果的前提下减少CPU的资源消耗。最重要的是,属性动画是通过调用get、set方法来真实的控制各View的属性值,基本可以实现所有的动画效果。所以View必须要提供setXxx方法,如果动画的时候没有传递初始值,那么还要提供getXxx方法,因为系统要去拿xxx属性的初始值(如果这条不满足,程序直接Crash) 。View的setXxx对属性xxx所做的改变必须能够通过某种方法反映出来,比如会带来ui的改变啥的(如果这条不满足,动画无效果但不会Crash)。
举一个最简单的例子:
Android属性动画(ObjectAnimator、PropertyValuesHolder、ValueAnimator、AnimatorSet)_第1张图片

    ObjectAnimator animator = ObjectAnimator.ofFloat(btn1, "translationX", 0, 500);     animator.setDuration(3000);    animator.start();

  ObjectAnimator.ofFloat(btn1, “translationX”, 0, 500); 这里第一个参数是要操纵的view,我的是一个button,第二个参数是要操纵的属性,最后一个参数是一个可变数组参数,传入属性变化的取值过程。和视图动画一样可以设置动画时长等属性。

常见的属性值:translationX、translationY:view对象从他布局容器的左上角坐标偏移的位置
       rotation、rotationX、rotationY:控制view围绕支点进行2D、3D的旋转
       scaleX、scaleY:控制view对象围绕支点进行2D缩放
       pivotX、pivotY:view对象的支点位置,围绕这个支点旋转缩放,默认为view对象的中心店
       x、y:view在容器中的位置
       alpha:view的透明度
       
  ObjectAnimator.ofFloat使用时要注意属性的数据类型,比如translationX属性使用了ObjectAnimator.ofInt(….)方法时,就会被认为报Method setTranslationX() with type int not found on target class 错误;同样一个属性没有对应get、set方法时,属性动画是不是就没办法了呢?答案肯定是否定的。可以通过一个自定义属性类或者包装类来间接的给这个属性增加get、set方法。
例如:

private static class ViewWrapper {        private View mTarget;        public ViewWrapper(View target) {            mTarget = target;        }        public int getWidth() {            return mTarget.getLayoutParams().width;        }        public void setWidth(int width) {            mTarget.getLayoutParams().width = width;            mTarget.requestLayout();        }    }

这样就给属性包装了一层,使用时只要操纵包装类即可:

        ViewWrapper wrapper = new ViewWrapper(mButton);        ObjectAnimator.ofInt(wrapper, width, 500).setDuration(5000).start();

Android属性动画(ObjectAnimator、PropertyValuesHolder、ValueAnimator、AnimatorSet)_第2张图片

PropertyValuesHolder

  在视图动画中用AnimationSet可以实现多个动画一起执行,在属性动画中,针对一个对象的多个属性进行操控,完成类似AnimationSet的效果可以通过PropertyValuesHolder来实现。
例如:

        PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);         PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);        PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("translationX",0, 500);        ObjectAnimator.ofPropertyValuesHolder(view,pvh1,pvh2,pvh3).setDuration(3000).start();

Android属性动画(ObjectAnimator、PropertyValuesHolder、ValueAnimator、AnimatorSet)_第3张图片

ValueAnimator

   ValueAnimator在属性动画中占非常重要的地位。他本身不提供任何动画效果,它更像一个数值发生器,用来产生一定规律的数字,从而让调动着来控制动画的实践过程。ValueAnimator的一般使用方法如下所示,通常情况下,在ValueAnimator的AnimatorUpdateListenerListener中监听数值的变化,从而完成动画的变换。

        ValueAnimator animator = ValueAnimator.ofFloat(0,100);        animator.setTarget(view);        animator.setDuration(1000).start();        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                Float value = (Float)animation.getAnimatedValue();                //use the value            }        });

动画的监听

一个完整的动画有Start、Repat、End、Cancel四个过程,通过Android提供了接口,可以很方便的监听这四个事件:

 animator.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {             }            @Override            public void onAnimationEnd(Animator animation) {            }            @Override            public void onAnimationCancel(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }        });

   大部分时候只关心onAnimationEnd事件,所以Android也提供了一个animatorListenerAdapter来让我们选择必要时间进行监听:

animator.addListener(new AnimatorListenerAdapter() {    @Override    public void onAnimationEnd(Animator animation) {    }});

AnimatorSet

   对于一个属性同时作用多个属性动画效果,可以用PropertyValuesHolder实现,但是用AnimatorSet不仅能实现这样的效果还可以更加精确的顺序控制。

        ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX",500f);         ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "scaleX",1f,0f,1f);        ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "scaleY",1f,0f,1f);        AnimatorSetset = new AnimatorSet();        set.setDuration(2000);        set.playSequentially(animator1,animator2,animator3);        set.start();

Android属性动画(ObjectAnimator、PropertyValuesHolder、ValueAnimator、AnimatorSet)_第4张图片

  在属性动画中AnimatorSet正是通过playTogether()、playSequentially()、animSet.play().with()、before()、after()这些方法来控制多个动画协同工作,从而做到对动画播放顺序的精确控制。

更多相关文章

  1. Android 控件布局实现卡片效果,阴影效果
  2. 【Android 基础】EditText的属性介绍
  3. 去掉ScrollVIew拉到尽头时再拉的阴影效果
  4. Android属性动画--补充说明&进阶

随机推荐

  1. 在c程序中,注释语句只能位于一条语句的后
  2. c++中不能重载的运算符有哪些
  3. c语言语句以什么结束
  4. textbox控件属性有哪些
  5. C语言中sizeof和strlen的区别是什么
  6. c++清屏函数是什么
  7. c++中头文件和源文件的区别是什么
  8. c源程序中main函数的位置是什么?
  9. c语言程序从哪里开始执行
  10. C++运算符中不能重载的是哪些