最近工作稍微清闲点,以前发现自己关于动画这块特别的弱,抽空学习了下属性动画,先总结下。
属性动画 从文字含义上就知道,它是通过改变对象的属性来实现动画效果。
属性动画和补间动画的区别:
1.补间动画改变的对象只能是View,属性动画可以改变任何对象(对非view对象使用属性动画的场景还没有遇到过,但确实可以)。
2.补间动画只能改变"alpha","rotate","scale","translate"四个属性,属性动画可以改变任何属性(属性必须有个set方法/get方法)。
属性动画的实现的步骤:
1.计算各帧对应的属性值
2.为指定的对象指定计算后的值,并刷新view
属性动画又是如何计算对顶额属性值了?
这里就得提到两个概率。
一 是
计算器(Evaluator),它是控制属性动画如何计算属性值(属性的类型可以是int,float,argb,自己定义的类型)。
对于int,float,argb类型Anroid已经提供有现成的IntEvaluator、FloatEvaluator、ArgbEvaluator计算器。对于没有没有
提供的类型,可以自己继承Type
Evaluator 来自定义。
例如:
public class MyPointEvaluator implements TypeEvaluator
{
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
//
fraction 是当前进度值从0-1
PointF startPoint = (PointF) startValue;
PointF endPoint = (PointF) endValue;
return new PointF(
startPoint.x + fraction * (endPoint.x - startPoint.x),
startPoint.y + fraction * (endPoint.y - startPoint.y));
}
}
二是
插值(Interpolator) 可以理解为控制动画的变化速度。Android提供了几种
—AccelerateInterpolator:动画从开始到结束,变化率是一个加速的过程。
—DecelerateInterpolator:动画从开始到结束,变化率是一个减速的过程。
—CycleInterpolator:动画从开始到结束,变化率是循环给定次数的正弦曲线。
—AccelerateDecelerateInterpolator:动画从开始到结束,变化率是先加速后减速的过程。
—LinearInterpolator:动画从开始到结束,变化率是线性变化。
也可以自定义
Interpolator,重写
getInterpolation方法
public class MyInterpolator implements Interpolator {
private float mFactor; private int i;
public MyInterpolator(int i){
this.i = i; }
@Override
public float getInterpolation(float input) {
switch(i){
case 1:mFactor = input;
break;
case 2:mFactor = input*input*input;
break; }
return mFactor;
} }
使用ObjectAnimator实现动画
ObjectAnimator.ofFloat 改变属性值为float类型的的方式 例如:ObjectAnimator.ofFloat(m_tv, "X", width); //X为m_tv 的一个属性
ObjectAnimator.ofInt
改变属性值为int类型的的方式
例如:ObjectAnimator.ofFloat(m_tv, "Y", width);
//Y为m_tv 的一个属性
ObjectAnimator.ofObject
改变属性值为其他类型的的方式 ObjectAnimator.ofObject(m_atv, "point",
new MyPointEvaluator(), new PointF(w, h), new PointF(x, y)); //
point 为
m_atv的类型为
PointF的属性
ObjectAnimator.ofPropertyValuesHolder 改变多个属性值
当我们想一次改变对象的多个属性的是时候使用
ofPropertyValuesHolder 方法。例如:
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", x1,x2);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", y1,y2
);
ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(m_tv, pvhX,
pvhY);
定义后
ObjectAnimator
后直接调用start(),即可执行。
补充:
1.
PropertyValuesHolder 的工厂方法里面,除了整形ofInt()、浮点型ofFloat()、Object类型ofObject()之外,还有一种:ofKeyframe()。
Keyframe是一个时间/值对,用于定义在某个时刻动画的状态。
每一个keyframe还可以拥有自己的interpolator,控制了前一个关键帧到这一个关键帧之间的时间动画行为。
一个例如用关键帧定义左右摇摆的动画
PropertyValuesHolder pvhTranslateX = PropertyValuesHolder.ofKeyframe(View.TRANSLATION_X,
Keyframe.ofFloat(0f, 0),
Keyframe.ofFloat(.10f, -delta),
Keyframe.ofFloat(.26f, delta),
Keyframe.ofFloat(.42f, -delta),
Keyframe.ofFloat(.58f, delta),
Keyframe.ofFloat(.74f, -delta),
Keyframe.ofFloat(.90f, delta),
Keyframe.ofFloat(1f, 0f)
ObjectAnimator.ofPropertyValuesHolder(view, pvhTranslateX).
setDuration(500);
2.
如果动画的对象是View,为了能显示动画效果,可能还需要在onAnimationUpdate()事件中监听调用View.invalidate()方法来刷新屏幕显示。但是View的定义的setter方法,
如setAlapha(),setTranslationX()等方法,都会自动调用invalidate()方法,不需要额外的调用
invalidate方法。