属性动画是在Android3.0后新增的效果,功能十分强大,它可以操作任意对象的属
性,而不仅仅只是View对象。在指定的时间内将对象的属性值变为另一个属性值。属性动画中有AnimatorSet,ValueAnimator,ObjectAnimator等。通过利用这些类实现绚丽的动画效果
ObjectAnimator alpha = ObjectAnimator.ofFloat(tv, "alpha", 1, .1f);
alpha.setDuration(5000);
alpha.setRepeatCount(ObjectAnimator.INFINITE);
alpha.setRepeatMode(ObjectAnimator.REVERSE);
alpha.start();
ObjectAnimator和ValueAnimator常用属性,ObjectAnimator继承自ValueAnimator
在ObjectAnimtoar类的静态方法中,有ofInt(),ofFloat(),ofArgb()..等表示操作的属性分辨是int,float,颜色类型
ofFloat()方法原型:
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)
属性动画可以在XML布局文件中设置,布局文件处于/res/animator目录下。
android:repeatCount="infinite"
android:startOffset="100"
android:repeatMode="reverse"
android:valueTo="100"
android:valueType="intType" />
startOffset:动画开始前的延时时间
其他属性在上面已经介绍了就不在多加阐述。
在代码中使用XML布局文件中的属性动画:
AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.animator_layout);
animatorSet.setTarget(tv);
animatorSet.start();
虽然两种方式都可以使用属性动画,还是建议在代码中创建,一个原因是创建比较简洁, 第二个是因为属性动画操作的是View的属性,而View的大部分属性其实是没办法事先确定好的,要依赖动态的创建属性动画。
作用:根据当前时间的流逝百分比计算出属性值变化的百分比,Android系统已经预设了一些常用的插值器:LinearInterpolator(线性插值器,匀速动画),AccelerateDecelerateInterpolator(加速减速插值器,先慢再快最后慢的动画效果),AccelerateInterpolator(加速插值器),DecelerateInterpolator(减速插值器)
作用:根据当前属性变化的百分比计算出改变后的属性值,Android系统预设的常用估值器有:IntEvaluator(整型估值器),FloatEvaluator(浮点型估值器),ArgbEvaluator(颜色估值器)
举个实际的例子:
将View的alpha属性在5000毫秒内从1.0变为0.0
ObjectAnimator alpha = ObjectAnimator.ofFloat(tv, "alpha", 1, 0f);
alpha.setDuration(5000);
alpha.setInterpolator(new LinearInterpolator());
alpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float animatedFraction = animation.getAnimatedFraction();
float animatedValue = (float) animation.getAnimatedValue();
}
});
alpha.start();
这是使用了线性插值器,默认使用AccelerateDecelerateInterpolator(加速减速插值器)
可以通过给动画添加AnimatorUpdateListener监听动画过程中属性值的变化。
关于动画的监听除了AnimatorUpdateListener,还有AnimationListener
public static interface AnimationListener {
void onAnimationStart(Animation animation); 动画开始
void onAnimationEnd(Animation animation); 动画结束
void onAnimationRepeat(Animation animation); 动画重复
}
属性动画可以操作任意的属性,前提是要满足两个条件,不然要不没效果,要不程序直接Crash
1.被操作的属性必须要有get及set方法,即如果操作x属性,要提供getX()和setX(),如果不满足,程序直接Crash
2.被操作的属性在进行属性动画改变时,必须能通过某种方式体现出来,例如可以引起UI的变化,如果不满足该条件,动画没有效果。
示例:
假设我们要用属性动画的方式改变TextView的width属性
ObjectAnimator.ofInt(tv, "width", 200).setDuration(2000).start();
这里会发现程序运行后没有效果,这里其实就没有同时满足上述的两个条件,width属性确实有提供getWidth()及setWidth()方法,getWidth()是View提供的方法,但是setWidth()却不是View提供的,他只是TextView提供的一个方法,调用setWidth无法改变宽度,所以这里只满足了条件1导致动画效果不生效。
对于以上的问题官方也给了三种解决方案:
这里需要说明的是因为我们操作的大部分属性都是系统提供的,我们是没有权限去改变,所以一般采用第二、三种方案。
采用第二种方式改变width:
public class ViewWrapper {
private View target;
public ViewWrapper(View source) {
this.target = source;
}
public int getWidth() {
return target.getLayoutParams().width;
}
public void setWidth(int width) {
target.getLayoutParams().width = width;
target.requestLayout();
}
}
使用装饰类:
ViewWrapper viewWrapper = new ViewWrapper(tv);
ObjectAnimator.ofInt(viewWrapper, "width", 200).setDuration(2000).start();