更简单的动画实现:ViewPropertyAnimator
前面学习了补间动画,属性动画创建动画,相对来说比较专业,但也显得繁琐。只要在View层中实现一个简单的动画需要创建各种辅助的类对象,还好Android又提供了一条路,让开发者直接操作View来添加动画。
1、ViewPropertyAnimator
Android比较让人头疼的是提供了很多方法可以实现相同的目的(API太多)。动画也是,前面已经学习了很多创建动画的方法,但是还有ViewPropertyAnimator类内部封装了Animator属性动画。
1.1、类简介
ViewPropertyAnimator类从API 12也就是Android 3.1开始引入Android。虽然是和动画相关的但是却进而View紧密联系,所以在android.view包中,而不是在android.animation包中。
构造函数是默认的包访问权限:
/**
* 构造函数,由View调用。
* 这在设计上是私有的,应用开发者应仅通过调用View.animate()来获得ViewPropertyAnimator。
*
* @param view The View associated with this ViewPropertyAnimator
*/
ViewPropertyAnimator(View view) {
mView = view;
view.ensureTransformationInfo();
}内部定义了如下常用用来关联View的一些属性常量,开发者仅需了解,都有对应的API方法调用,后面再介绍。
/**
* Constants used to associate a property being requested and the mechanism used to set
* the property (this class calls directly into View to set the properties in question).
*/
static final int NONE = 0x0000;
static final int TRANSLATION_X = 0x0001;
static final int TRANSLATION_Y = 0x0002;
static final int TRANSLATION_Z = 0x0004;
static final int SCALE_X = 0x0008;
static final int SCALE_Y = 0x0010;
static final int ROTATION = 0x0020;
static final int ROTATION_X = 0x0040;
static final int ROTATION_Y = 0x0080;
static final int X = 0x0100;
static final int Y = 0x0200;
static final int Z = 0x0400;
static final int ALPHA = 0x0800;1.2、获取实例
ViewPropertyAnimator类不是由调用方构造的,因为该类的构造函数默认包访问权限,应用层开发者无法调用。只能通过调用View的animate()方法获得返回的实例。
ViewPropertyAnimator viewPropertyAnimator = mImageView.animate();调用View.animate()将返回对该视图相应的ViewPropertyAnimator对象的引用。
/**
* 此方法返回一个ViewPropertyAnimator对象,该对象可用于为该View上的特定属性设置动画。
*
* @return ViewPropertyAnimator 与此视图关联的ViewPropertyAnimator。
*/
public ViewPropertyAnimator animate() {
if (mAnimator == null) {
mAnimator = new ViewPropertyAnimator(this);
}
return mAnimator;
}1.3、适合场景说明
①业务使用非常方便,就地建立动画,立即生效开始执行(startDela()设置延迟除外)
②组合动画中所有的动画都是一起播放;如果有一定序列的播放动画还是使用AnimatorSet进行更专业的设计。
③对于通用的View动画,可以写到res/anim资源中复用;复杂的View动画,还是使用ObjectAnimator、PropertyValuesHolder设计动画。
④对于性能方面并无影响方便开发者专注动画需求的实现,代码更简洁。
2、方法介绍
方法不需要记住,或主需要记住最常用的即可。而且方法的命名设计都很讲究
①设置动画方法名以By结尾的是相对当前值为基准改变的值,而没有By结尾的方法含义是设置成指定值。这其中的区别从源码就能看出来,最终都是调用animatePropertyBy(int constantName, float startValue, float byValue)方法
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);
}②用于设置动画的方法都会返回自身this,方便一口气链式调用设置很多动画属性。
③重复在某个属性上设置的动画会将前一个取消,比如先设置了rotation(),有调用了rotationBy()那么之前设置rotation属性的方法将失效。
2.1、旋转
①rotation(float value):设置该View的rotation属性为value值
②rotationBy(float value):在当前View已有的rotation旋转值基础上,再旋转values值
③rotationX(float value)
④rotationXBy(float value)
⑤rotationY(float value):此方法将View的rotationY属性动画化为指定的值。 已在该属性上运行的动画将被取消。
⑥rotationYBy(float value)
2.2、放缩
①scaleX(float value):
②scaleXBy(float value):
③scaleY(float value):
④scaleYBy(float value):
2.3、平移
①translationX(float value)
②translationXBy(float value)
③translationY(float value)
④translationYBy(float value)
⑤translationZ(float value)
⑥translationZBy(float value)
2.4、透明度
①alpha(float value)
②alphaBy(float value)
2.5、(x,y,z)
①x(float value):动画中调用View的setX()方法设置此视图的可视x位置(以像素为单位)。这等效于将setTranslationX(float)属性设置为传入的x值与当前getLeft()之间的差。
②xBy(float value)
③y(float value)
④yBy(float value)
⑤z(float value)
⑥zBy(float value)
2.6、setter和getter方法
①setDuration(long duration):设置动画时长
②setStartDelay(long startDelay):设置动画开始延迟startDelay毫秒
③setInterpolator(TimeInterpolator interpolator):设置插值器
④setListener(Animator.AnimatorListener listener):设置AnimatorListener监听器
⑤setUpdateListener(ValueAnimator.AnimatorUpdateListener listener):设置AnimatorUpdateListener动画更新监听器
⑥getDuration()
⑦getStartDelay()
⑧getInterpolator()
⑨getListener()
⑩getUpdateListener()
2.7、其它
①start():可选。因为ViewPropertyAnimator构造设置完成之后自动开始在合适的实际执行动画
②cancel():取消当前正在运行或待处理的所有属性动画
③withStartAction(Runnable runnable):动画运行时要执行的动作。如果设置startDelay()则在实际动画开始时,该操作将在startDelay到期后运行
④withEndAction(Runnable runnable)动画结束时要执行的动作Runnable。仅当动画正常结束时才运行该动作;如果在该动画期间取消了ViewPropertyAnimator,则可运行对象将不会运行
⑤withLayer():与此ViewPropertyAnimator关联的View在下一个动画期间将其View.setLayerType(int, android.graphics.Paint)设置 View.LAYER_TYPE_HARDWARE
3、示例
①先通过要添加动画的View拿到ViewPropertyAnimator实例
ViewPropertyAnimator viewPropertyAnimator = mImageView.animate();②要实现旋转、透明度、放缩的动画,一气呵成:
viewPropertyAnimator
.alpha(0.5f)
.scaleX(0.5f)
.scaleY(0.5f)
.rotationY(90)
.rotationYBy(180) //由于再次设置了rotation属性,前面设置rotation会被取消
.setDuration(1000) //方便的设置动画持续时长
.setInterpolator(new LinearInterpolator()) //设置该动画执行过程中的插值器
.withEndAction(() -> {
Toast.makeText(context, "动画执行完毕", Toast.LENGTH_SHORT).show();
});
参考资料:

