简述:
能不用PropertyAnimation就不用,如果只是做View就用ViewPropertyAnimator多个属性一起改。ViewAnimation并没有改变View的属性,点击还是原来区域。
Property Animation 和 View Animation
ViewAnimation有很强的局限性:只能操作View对象、View的部分属性(不包含背景色)、只是改变View在哪里绘制,没有改变相应逻辑(比如Button移动,你点击的地方仍旧是以前的,相应逻辑需要你自己写)。
因为ViewAnimation改变View的绘制,所以是通过操控他的父View,ViewGroup来完成的,因为View本身没有这样的属性。所以View对象本身没有变化,导致View的行为操作,仍旧停留在原来区域。3.0后添加了get、set方法,就行bug修复。
而PropertyAnimation可以View对象的真实属性(调用方法),所以View会自动调用invalidate方法(View set方法会调)
然而ViewAnimation体系启动时间更少、需要代码更少。所以了ViewAnimation够用了,就别用PropertyAnimation。
PropertyAnimation API:
ValueAnimator:
就是指定数值区间、时间,然后在监听器中做你想做的事情(如动画)。(也就是改什么属性是你在回调中写的,实际上你只控制了速度),Animation有两个阶段:算数值、设置对象的属性值。 ValueAnimator只负责第一个阶段,第二个阶段程序员自己写。
获取数值的API是getAnimatedValue()
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f); animation.setDuration(1000); animation.start();
ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue); animation.setDuration(1000); animation.start();
ObjectAnimator:
上述的两个阶段都负责,所以要指定属性名称。类需要提供set和get方法,方法的命名方式要符合驼峰命名。如alpha属性,要有个setAlpha,getAlpha防范。如果三个次,如helloWorld,那set方法就是setHelloWorld
ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f); anim.setDuration(1000); anim.start();根据不同的属性值,你可能需要调用invalidate方法,在
onAnimationUpdate()
这个回调中调用。例如Drawable对象的color属性,就只有你主动调用才刷新。而View类的所有带set***方法的属性***都会自己主动刷新,就不用你再调用了。
AnimatorSet:
就是让多个Animator,按照某种顺序发生(同时了、一个结束了、一个开始了)。
AnimatorSet bouncer = new AnimatorSet(); bouncer.play(bounceAnim).before(squashAnim1); bouncer.play(squashAnim1).with(squashAnim2); bouncer.play(squashAnim1).with(stretchAnim1); bouncer.play(squashAnim1).with(stretchAnim2); bouncer.play(bounceBackAnim).after(stretchAnim2); ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); fadeAnim.setDuration(250); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(bouncer).before(fadeAnim); animatorSet.start();
对ViewGroup布局的改变:
使用LayoutTransition
APPEARING
- A flag indicating the animation that runs on items that are appearing in the container.CHANGE_APPEARING
- A flag indicating the animation that runs on items that are changing due to a new item appearing in the container.DISAPPEARING
- A flag indicating the animation that runs on items that are disappearing from the container.CHANGE_DISAPPEARING
- A flag indicating the animation that runs on items that are changing due to an item disappearing from the container.
使用Interpolator:
加速器提供时间和返回值之间的映射关系。自己写就继承TimeInterpolator,或者用android.view.animation包里的。
AccelerateDecelerateInterpolator
public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; }
监听器:实现接口Animator.AnimatorListener,或者有空方法让你重写的AnimatorListenerAdapter类。
使用自定义的TypeEvaluator:
public class FloatEvaluator implements TypeEvaluator { public Object evaluate(float fraction, Object startValue, Object endValue) { float startFloat = ((Number) startValue).floatValue(); return startFloat + fraction * (((Number) endValue).floatValue() - startFloat); } }
监听关键的帧:
Keyframe kf0 = Keyframe.ofFloat(0f, 0f); Keyframe kf1 = Keyframe.ofFloat(.5f, 360f); Keyframe kf2 = Keyframe.ofFloat(1f, 0f); PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2); ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation) rotationAnim.setDuration(5000ms);
新增API中的属性:
translationX
andtranslationY
: These properties control where the View is located as a delta from its left and top coordinates which are set by its layout container.rotation
,rotationX
, androtationY
: These properties control the rotation in 2D (rotation
property) and 3D around the pivot point.scaleX
andscaleY
: These properties control the 2D scaling of a View around its pivot point.pivotX
andpivotY
: These properties control the location of the pivot point, around which the rotation and scaling transforms occur. By default, the pivot point is located at the center of the object.x
andy
: These are simple utility properties to describe the final location of the View in its container, as a sum of the left and top values and translationX and translationY values.alpha
: Represents the alpha transparency on the View. This value is 1 (opaque) by default, with a value of 0 representing full transparency (not visible).
例子
ViewPropertyAnimator:
对比:
Multiple ObjectAnimator objects
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(animX, animY); animSetXY.start();
One ObjectAnimator
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f); ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
ViewPropertyAnimator
myView.animate().x(50f).y(100f);
使用XML:
为了区分ViewAnimation,需要在res/animator/目录取代res/anim/目录,要预览的话,系统只会在上述路径下扫描PropertyAnimation
ValueAnimator
-<animator>
ObjectAnimator
-<objectAnimator>
AnimatorSet
-<set>
<set android:ordering="sequentially"> <set> <objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> <objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> </set> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/> </set>
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();