本文转载自微信公众号《Android开发编程》,作者Android开发编程。转载本文请联系Android开发编程公众号。前言大部分常用的动画都是针对View的,而View往往需要集中动画混合在一起。因此,提供了一个ViewPropertyAnimator类,可以快速实现多个动画的混合;ViewPropertyAnimator从名字就可以看出。API12中提供了专用的View属性动画;ViewPropertyAnimator专门用于操作View动画,语法更简洁,使用更方便;让我们看看今天如何使用它;一、ViewPropertyAnimator详解1、获取对象ViewPropertyAnimator没有构造函数,通过View的.animate()方法可以方便的获取ViewPropertyAnimator对象,此时获取的动画对象专门用于操作当前视图;publicViewPropertyAnimatoranimate(){if(mAnimator==null){mAnimator=newViewPropertyAnimator(this);}returnmAnimator;}2、基本函数属性介绍alpha(floatvalue)设置View的透明度,value的最终值;alphaBy(floatvalue)设置View的透明度,value是基于view当前值的偏移量;rotation(floatvalue):旋转View,正值顺时针,负值逆时针,value终值;rotationBy(floatvalue):旋转,基于当前值的偏移;rotationX(floatvalue):绕x轴旋转;rotationXBy(floatvalue):基于View旋转,以value为偏移量绕X轴旋转;rotationY(floatvalue):绕Y轴旋转;rotationYBy(floatvalue):以当前旋转为基础,绕Y轴旋转;scaleX(floatvalue):缩放视图在X轴方向的大小;缩放XBy(floatvalue):根据当前View的缩放比例,在X轴方向缩放视图;scaleY(floatvalue):缩放视图在Y轴方向的大小;scaleYBy(floatvalue):根据当前View的缩放比例对视图进行缩放,对视图的Y轴方向进行缩放;translationX(floatvalue):沿X轴方向平移,值大于0,X轴正方向;translationXBy(floatvalue):带偏移量的翻译;translationY(floatvalue):沿Y轴方向平移,若该值大于0,则沿Y轴正方向平移;translationYBy(floatvalue):基于当前值在Y轴方向平移;x(floatvalue):根据当前值,修改视图的X坐标;xBy(floatvalue):根据当前值修改视图的X坐标;y(floatvalue):根据当前值修改View的Y坐标;yBy(floatvalue):基于当前值,修改View的Y坐标;z(floatvalue):根据当前值修改View的Z坐标;zBy(floatvalue):根据当前值Z坐标修改View;3.基本使用常用方法btnShow.animate().setDuration(5000)//transparency.alpha(0).alphaBy(0)//rotation.rotation().rotationBy(360).rotationX(360).rotationXBy(360).rotationY(360).rotationYBy(?)//缩放.scaleX(1).scaleXBy(1).scaleY(1).scaleYBy(1)//Translation.translationX(100).translationXBy(100).translationY(100).translationYBy(100).translationZ(100).translationZBy(100)//改变屏幕上的坐标.x(10).xBy(10).y(10).yBy(10).z(10).zBy(10)//监控等设置.setInterpolator(newBounceInterpolator()).setStartDelay(1000).setListener(newAnimator.AnimatorListener(){@OverridepublicvoidonAnimationStart(Animatoranimation){}@OverridepublicvoidonAnimationEnd(Animatoranimation){}@OverridepublicvoidonAnimationCancel(Animatoranimation){}@OverridepublicvoidonAnimation(AnimatorAnimation){}@OverridepublicvoidonAnimation(AnimationRepeat)}).setUpdateListener(newValueAnimator.AnimatorUpdateListener(){@OverridepublicvoidonAnimationUpdate(ValueAnimatoranimation){}}).withEndAction(newRunnable(){@Overridepublicvoidrun(){Log.i(TAG,"run:end");}}).withStartAction(newRunnable(){@Overridepublicvoidrun(){Log.i(TAG,"run:start");}}).start();4.添加监听setUpdateListener:添加动画属性变化监听setListener:添加动画状态监听ViewPropertyAnimatorviewPropertyAnimator=gongxiang.animate().setDuration(3000).x(700).y(700).rotation(270).alpha(0.5f).setUpdateListener(newValueAnimator.AnimatorUpdateListener(){@OverridepublicvoidonAnimationUpdate(ValueAnimatoranimation){);}}).setListener(newAnimatorListenerAdapter(){@OverridepublicvoidonAnimationCancel(Animatoranimation){super.onAnimationCancel(动画);}@OverridepublicvoidonAnimationEnd(Animatoranimation){super.onAnimationEnd(动画);System.out.println("=========onAnimationEnd=======");}@OverridepublicvoidonAnimationRepeat(Animatoranimation){super.onAnimationRepeat(动画);}@OverridepublicvoidonAnimationStart(Animatoranimation){super.onAnimationStart(动画);System.out.println("=========onAnimationStart=======");}@OverridepublicvoidonAnimationPause(动画动画){super.onAnimationPause(动画);}@OverridepublicvoidonAnimationResume(动画动画){super.onAnimationResume(动画);}});二、基础原理1、执行动画基础步骤如下通过test.animate()获取ViewPropertyAnimator对象;调用alpha、translationX等方法返回当前ViewPropertyAnimator对象,可以继续链式调用;alpha、translationX等内部方法最终调用了animatePropertyBy(intconstantName,floatstartValue,floatbyValue)方法;在animatePropertyBy方法中,会将alpha、translationX等方法的操作封装到NameVauleHolder中,并将每个NameValueHolder对象添加到准备列表mPendingAnimations中;animatePropertyBy方法会启动mAnimationStarter,调用startAnimation,开始动画;startAnimation方法将创建一个ValueAnimator对象来设置内部Listener;AnimatorEventListener,并将mPendingAnimations和需要动画的属性名封装成一个PropertyBundle对象,最后mAnimatorMap保存了当前的Animator和对应的PropertyBundle对象,这个Map会在animatePropertyBy方法和Animator监听器mAnimatorEventListener中用来启动动画;在动画监听器的onAnimationUpdate方法中设置所有属性的变化值,并通过RenderNode类优化绘制性能,最后刷新界面;2、startAnimation()源码/***StartstheunderlyingAnimatorforasetofproperties。/privatevoidstartAnimation(){if(mRTBackend!=null&&mRTBackend.startAnimation(this)){return;}mView.setHasTransientState(true);//创建ValueAnimatorValueAnimatoranimator=ValueAnimator.ofFloat(1.0f);//克隆一个mPendingAnimations赋值给nameValueListArrayList
