之前使用过View Animation ,但是据说,他们只能实行一些简单的动画,比如要实现一个3D的旋转的功能就不行。为此出现了Property Animation。
从名字我们可以看出,他们都是动画,因此,彼此间一定有很多的共性,揣测一下,觉得实现的原理都是一样的,知识在用法上可能属性动画更灵活一些,本质都是一样的。
属性动画最重要的两个类 ObjectAnimator 、 ValueAnimatior 他们都是动画的执行类。
AnimatorSet: 由于控制一组动画的执行:线性、一起、每个动画的执行顺序等。
AnimatorInflater: 加载动画的xml文件
TypeEvaluator:类型估值,主要用于设置动画操作属性的值,这个是跟View Animation相比 最大的特色。
接下来直接demo:
public void startAnim(View view) {
//内部通过反射查找 属性名对应的方法,如果找不到属性名,可以手动调用addUpdateListener方法实现动画
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "rotationX", 0.0f,360.0f);
animator.setDuration(3000);
animator.start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// TODO Auto-generated method stub
float rotation=(Float) animation.getAnimatedValue();
imageView.setRotationX(rotation);
}
});
}
参数 rotationX 代表属性名,这不是随便取的名字啊,亲。内部通过反射查找属性名来判断动画类型。
最后两个参数代表起始和结束位置。
如果属性名错误,反射没有匹配到。则可以手动执行addUpdateListener方法不断的刷新view,有点类似animation里面的applyTransformation方法,在动画的过程中,方法一直执行。10ms or 20ms 刷新一次。
getAnimationValue得到的值就是后两个参数范围内数。
灵活的地方在于,它可以一次实现多了动画效果。虽然View Animation也可以通过 AnimationSet实现,但过于累赘。
拜代码:
public void rotateyAnimRun(final View view)
{
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "joven", 1.0F, 0.0F).setDuration(500);//
anim.start();
anim.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(cVal);
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
}
实现缩小,淡出的效果。这个算是灵活使用吧,应该不是正规军。正规军如下
2,ObjectAnimator 的另一种实现方式
PropertyValuesHolder alpha=PropertyValuesHolder.ofFloat("alpha", 1.0f,0.0f);
PropertyValuesHolder scaleX=PropertyValuesHolder.ofFloat("scaleX", 1.0f,0.0f);
PropertyValuesHolder scaleY=PropertyValuesHolder.ofFloat("scaleY", 1.0f,0.0f);
ObjectAnimator animator2=ObjectAnimator.ofPropertyValuesHolder(imageView,alpha, scaleX,scaleY);
animator2.setDuration(2000).start();
实现同一个同事多个动画。
3,ValueAnimator实现动画
从类名可以看出,ValueAnimator的关键是value,ObjectAnimator 的关键是object。
ValueAnimator设置了动画的参数,但没有指定动画对象和动画类型。有点降低耦合的意思。
拜代码:
/**
* 自由落体
* @param view
*/
public void verticalRun( View view)
{
ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight
- mBlueBall.getHeight());
animator.setTarget(mBlueBall);
animator.setDuration(1000).start();
// animator.setInterpolator(value)
animator.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
mBlueBall.setTranslationY((Float) animation.getAnimatedValue());
}
});
}
4,TypeValue
当要计算动画坐标的话,就需要重写TypeValue了,计算动画数值的时候自动调用setEvaluator方法。这个是真的和applyTransformation类似了,根据时间半分比计算相关参数
/**
* 抛物线
* @param view
*/
public void paowuxian(View view)
{
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(3000);
valueAnimator.setObjectValues(new PointF(0, 0));
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setEvaluator(new TypeEvaluator<PointF>()
{
// fraction = t / duration
@Override
public PointF evaluate(float fraction, PointF startValue,
PointF endValue)
{
Log.e(TAG, fraction * 3 + "");
// x方向200px/s ,则y方向0.5 * 10 * t
PointF point = new PointF();
point.x = 200 * fraction * 3;
point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);
return point;
}
});
valueAnimator.start();
valueAnimator.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
PointF point = (PointF) animation.getAnimatedValue();
mBlueBall.setX(point.x);
mBlueBall.setY(point.y);
}
});
}
addListener
6,AnimatorSet
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.playTogether(animator,animator2);
animatorSet.start();
AnimatorSet animSet = new AnimatorSet();
animSet.play(anim1).with(anim2);
animSet.play(anim2).with(anim3);
animSet.play(anim4).after(anim3);
animSet.setDuration(1000);
animSet.start();