美文网首页
7.ViewPropertyAnimator

7.ViewPropertyAnimator

作者: Varmin | 来源:发表于2017-05-30 01:46 被阅读0次

    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<Animator> 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);
        }
    

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

    原理流程: image

    相关文章

      网友评论

          本文标题:7.ViewPropertyAnimator

          本文链接:https://www.haomeiwen.com/subject/ymwlfxtx.html