7.ViewPropertyAnimator

ViewPropertyAnimator概述

属性动画已不再是针对于View而进行设计的了,而是一种对数值不断操作的过程,我们可以将属性动画对数值的操作过程设置到指定对象的属性上来,从而形成一种动画的效果。虽然属性动画给我们提供了ValueAnimator类和ObjectAnimator类,在正常情况下,基本都能满足我们对动画操作的需求,但ValueAnimator类和ObjectAnimator类本身并不是针对View对象的而设计的,而我们在大多数情况下主要都还是对View进行动画操作的,因此Google官方在Android 3.1系统中补充了ViewPropertyAnimator类,这个类便是专门为View动画而设计的。

优点:

  • 专门针对View对象动画而操作的类。
  • 提供了更简洁的链式调用设置多个属性动画,这些动画可以同时进行的。
  • 拥有更好的性能,多个属性动画是一次同时变化,只执行一次UI刷新(也就是只调用一次invalidate,而n个ObjectAnimator就会进行n次属性变化,就有n次invalidate)。
  • 每个属性提供两种类型方法设置。scaleX()/scaleXBy()
  • 该类只能通过View的animate()获取其实例对象的引用。

用法:链式调用,自动start,同时一次UI刷新, 简化流程提高效率。

AnimatorSet set = new AnimatorSet();
set.playTogether( ObjectAnimator.ofFloat(btn,"alpha",0.5f),
        ObjectAnimator.ofFloat(btn,"rotation",360),
        ObjectAnimator.ofFloat(btn,"scaleX",1.5f),
        ObjectAnimator.ofFloat(btn,"scaleY",1.5f),
        ObjectAnimator.ofFloat(btn,"translationX",0,50),
        ObjectAnimator.ofFloat(btn,"translationY",0,50)
);
set.setDuration(5000).start();
//自动调用start方法
btn.animate().alpha(0.5f).rotation(360).scaleX(1.5f).scaleY(1.5f)
              .translationX(50).translationY(50).setDuration(5000);

每个属性,两种类型方法设置:

  • rotationX(20) 改变到某个值。 旋转到20度。再调用一次的话,由于已经到20度的位置,便不在有变化。
  • rotationXBy(20) 改变某个值的量。 旋转20度。再调用一次的话,继续旋转20度,到40度的位置。
public ViewPropertyAnimator scaleY(float value) {
        animateProperty(SCALE_Y, value);
        return this;
    }

public ViewPropertyAnimator scaleYBy(float value) {
    animatePropertyBy(SCALE_Y, value);
    return this;
    
-----------------------------------------------------------------------------

private void animateProperty(int constantName, float toValue) {
        float fromValue = getValue(constantName);
        float deltaValue = toValue - fromValue;
        animatePropertyBy(constantName, fromValue, deltaValue);
    }

private void animatePropertyBy(int constantName, float byValue) {
        float fromValue = getValue(constantName);
        animatePropertyBy(constantName, fromValue, byValue);
    }
    
----------scale/rotation/alpha等方法,到最后都是调用该方法-----------------------------------

/**
     * Utility function, called by animateProperty() and animatePropertyBy(), which handles the
     * details of adding a pending animation and posting the request to start the animation.
     *
     * @param constantName The specifier for the property being animated
     * @param startValue The starting value of the property
     * @param byValue The amount by which the property will change
     */
    private void animatePropertyBy(int constantName, float startValue, float byValue) {
        // First, cancel any existing animations on this property
        if (mAnimatorMap.size() > 0) {
            Animator animatorToCancel = null;
            Set animatorSet = mAnimatorMap.keySet();
            for (Animator runningAnim : animatorSet) {
                PropertyBundle bundle = mAnimatorMap.get(runningAnim);
                // 如果在该属性上已经有动画,则结束该属性上的动画。
                if (bundle.cancel(constantName)) {
                    // property was canceled - cancel the animation if it's now empty
                    // Note that it's safe to break out here because every new animation
                    // on a property will cancel a previous animation on that property, so
                    // there can only ever be one such animation running.
                    if (bundle.mPropertyMask == NONE) {
                        // the animation is no longer changing anything - cancel it
                        animatorToCancel = runningAnim;
                        break;
                    }
                }
            }
            if (animatorToCancel != null) {
                animatorToCancel.cancel();
            }
        }

        // 封装该属性和值,放入集合中
        NameValuesHolder nameValuePair = new NameValuesHolder(constantName, startValue, byValue);
        mPendingAnimations.add(nameValuePair);
        mView.removeCallbacks(mAnimationStarter);
        //虽然每次操作属性都post了该Runnable类,但是每次都把原来的移除了,始终都在维护一个最新的集合post。
        //TODO ??? post给系统,然后系统按顺序调用,假如系统很闲,post了立马就start,那么下一个属性设置的时候呢,怎么保证每个属性的设置都放到集合里了才开始start?
        mView.postOnAnimation(mAnimationStarter);
    }

后续监听什么的,还没研究。 资料链接。

原理流程:
7.ViewPropertyAnimator_第1张图片
image

你可能感兴趣的:(7.ViewPropertyAnimator)