http://keeganlee.me/post/android/20151026
属性动画和视图动画的区别:
视图动画只能作用于View,而且视图动画改变的只是View的绘制效果,View真正的属性并没有改变。比如,一个按钮做平移的动画,虽然按钮的确做了平移,但按钮可点击的区域并没随着平移而改变,还是在原来的位置。而属性动画则可以改变真正的属性,从而实现按钮平移时点击区域也跟着平移。
通俗点说,属性动画其实就是在一定时间内,按照一定规律来改变对象的属性,从而使对象展现出动画效果。
属性动画主要有三个元素:
<animator>
、
<objectAnimator>
、
<set>
。
相对应的有三个类:
ValueAnimator
、
ObjectAnimator
、
AnimatorSet
。
ValueAnimator
是基本的动画类,处理值动画,通过监听某一值的变化,进行相应的操作。
ObjectAnimator
是
ValueAnimator
的子类,处理对象动画。
AnimatorSet
则为动画集,可以组合另外两种动画或动画集。相应的三个标签元素的关系也一样。
样式开发主要还是用xml的形式,所以这里主要还是讲标签的用法。
<animator>
标签与对应的
ValueAnimator
类提供了属性动画的核心功能,包括计算动画值、动画时间细节、是否重复等。执行属性动画分两个步骤:
- 计算动画值
- 将动画值应用到对象和属性上
ValuAnimiator
只完成第一步,即只计算值,要实现第二步则需要在值变化的监听器里自行更新对象属性
<objectAnimator>
与
<animator>
的例子相比,就只是多了一个
android:propertyName
的属性,
android:propertyName
目标对象的属性名,要求目标对象必须提供该属性的setter方法,如果动画的时候没有初始值,还需要提供getter方法
例如,
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:propertyName="width"
android:valueFrom="100"
android:valueTo="20"
android:valueType="intType" />
本意是想控制view的宽度从100%,缩放到20%,(一开始宽度是matchparent),但是view没有setWidth的属性,并且缩放的是一个比例,这是要进行计算的,所以定义了一个view的包装类ViewWrapper
private static class ViewWrapper {
private View target; //目标对象
private int maxWidth; //最长宽度值
public ViewWrapper(View target, int maxWidth) {
this.target = target;
this.maxWidth = maxWidth;
}
public int getWidth() {
return target.getLayoutParams().width;
}
public void setWidth(int widthValue) {
//widthValue的值从100到20变化
target.getLayoutParams().width = maxWidth * widthValue / 100;
target.requestLayout();
}
}
public void onScaleWidth(View view) {
// 获取屏幕宽度
int maxWidth = getWindowManager().getDefaultDisplay().getWidth();
// 将目标view进行包装
ViewWrapper wrapper = new ViewWrapper(view, maxWidth);
// 将xml转化为ObjectAnimator对象
ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_animator);
// 设置动画的目标对象为包装后的view
objectAnimator.setTarget(wrapper);
// 启动动画
objectAnimator.start();
}