Property Animation是android 3.0推出的另一种动画方式,能够构建线性和非线性动画,他的api被放在android.animation这个包下
在之前介绍view animation时说要比较Property Animation 和View Animation的区别,那么他们到底有哪些区别呢?
1、view animation只能够对view对象添加动画,如果要对非view对象添加动画,那么你就只能自己去实现代码了。例如:view animation
中能够对view实现scaling和rotation动画,但是却无法对背景颜色这些非view对象实现动画效果。
2、在view animation对view控件实行动画时,如果view控件的位置发生改变,这种改变是一种伪改变,如:我对一个button添加translation
动画时,在他移动的时候如果我们要触发button事件,但点击这个移动的button是无效的,无法触发事件,必须得点击他原来的位置。
3、Property animation已经成熟了,上面的那些限制都没有了,所以大多数情况下应该使用property animation,view animation就是实现起
来比property animation的代码量少一些。
通过以上比较我们就是知道了android 退出Property Animation就是为了增加新的动画功能以及取代View Animation,因为View Animation能够
做的动画Property Animation都能够做而且做的更好。所以如果你学会了Property Animation之后View Animation就可以忘记了,下面我们就来
介绍 Property Animation的用法。我们不是说Property Animation的功能已经完全替代了View Animation了吗,那么在Property Animation中去
实现View Animation的功能是怎样做的呢?
例子一:实现一个按钮被点击后能够水平缩小放大的动画(xml实现)
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:propertyName="scaleX" android:duration="2000" android:valueFrom="1.0" android:valueTo="2.0" android:repeatCount="1" android:repeatMode="reverse"> </objectAnimator>
scale = (Button)findViewById(R.id.scale); scale.setOnClickListener(this); ObjectAnimator objectScale = (ObjectAnimator)AnimatorInflater.loadAnimator(this, R.animator.objectanimator1); objectScale.setTarget(scale);
然后在按钮的事件监听中调用start()方法就行:objectScale.start() 这样一个简单的缩小放大的动画便完成了,那么通过Java代码怎样实现呢?
Java代码实现方法(Java代码实现方法):
object = ObjectAnimator.ofFloat(scale,"scaleX", 1.0f,2.0f); object.setDuration(2000); object.setRepeatCount(1); object.setRepeatMode(Animation.REVERSE);
然后在按钮的事件监听中调用start()方法:object.start() 这样通过Java代码也能够实现上面xml所实现的效果。
那么问题来了,如果我想实现多种效果混合的动画呢?在View Animation中xml实现方式我们可以通过set根元素添加多种动画效果,Java代码
则通过AnimationSet可以添加多种动画效果,那么在Property Animation是怎样实现的呢?
通过xml方式实现(xml实现)
在Property Animation中xml的实现方式也是在set根元素下添加多种动画
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together"> <objectAnimator android:propertyName="scaleX" android:duration="2000" android:valueFrom="1.0" android:valueTo="2.0" android:repeatCount="1" android:repeatMode="reverse"> </objectAnimator> <objectAnimator android:propertyName="scaleY" android:duration="2000" android:valueFrom="1.0" android:valueTo="2.0" android:repeatCount="1" android:repeatMode="reverse"> </objectAnimator> </set>
AnimatorSet animatorSet = (AnimatorSet)AnimatorInflater.loadAnimator(this, R.animator.set1); animatorSet.setTarget(scale_set);
然后通过AnimatorSet将xml文件进行加载,最后在按钮的监听事件中调用start()方法:animatorSet.start()。看见没有在View Animation中是AnimationSet
类实现的在Property Animation中是AnimatorSet类实现的。
那么Java代码的方式是怎样实现的呢?(Java代码实现方法)
set = new AnimatorSet(); ObjectAnimator object1 = ObjectAnimator.ofFloat(scale_set, "scaleX", 1.0f,2.0f); object1.setDuration(2000); object1.setRepeatCount(1); object1.setRepeatMode(Animation.REVERSE); ObjectAnimator object2 = ObjectAnimator.ofFloat(scale_set, "scaleY", 1.0f,2.0f); object2.setDuration(2000); object2.setRepeatCount(1); object2.setRepeatMode(Animation.REVERSE); set.playTogether(object1,object2); set.setDuration(2000);
然后也在按钮的事件监听中调用start()方法:set.start()。这样混合效果的动画xml实现方式以及Java代码的实现方式就讲完了。
在Java代码中除了使用ObjectAnimator和AnimatorSet来实现,还能够通过其他方法来实现动画效果
1、通过PropertyValuesHolder和ObjectAnimator实现AnimatorSet类所实现的效果
//AnimatorSet能够实现一个对象多种动画效果,通过PropertyValuesHolder也能够实现 //方法:先使用PropertyValuesHolder定义多种动画效果,然后将其设置进ObjectAnimator中,进而调用ObjectAnimator //的start()方法启动动画 PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX", 1.0f,2.0f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY", 1.0f,2.0f); ObjectAnimator scaleAnimator = ObjectAnimator.ofPropertyValuesHolder(scale, pvhX,pvhY); scaleAnimator.setDuration(2000); scaleAnimator.setRepeatCount(1); scaleAnimator.setRepeatMode(Animation.REVERSE); scaleAnimator.start();
2、通过ViewPropertyAnimator能够实现简单的混合动画,能够简单到什么程度呢?
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(animX, animY); animSetXY.start();
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f); ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
上面两种实现方式用一行代码就能够实现:
myView.animate().x(50f).y(100f);
如果要对view实现简单的Property Animation那么就可以使用这种方式,他不但高效而且可读性也强。至于具体ViewPropertyAnimator的优势在哪
里我们可以去查看android的这篇官方博客:http://android-developers.blogspot.com/2011/05/introducing-viewpropertyanimator.html
好了以上就是基本上就是Property Animation实现动画的基本实现方式,下面我们就来更深入的介绍一下Property Animation的其他方式
ValueAnimator Evaluators以及Interpolators的用法
我们知道Property Animation能够创建非线性动画,何为非线性?非线性变化频率以及变化的位置不是均匀或者直线的。
ValueAnimator是Property Animation中最要的一个类,所有的非线性动画的创建都要通过他来实现,ObjectAnimator就是继承于这个类,
ValueAnimator能够记录动画运行的时间点以及轨迹,那么他是怎样实现的这些功能的呢?他是通过封装Evaluators以及Intepolators来实现的。
Evaluators是Property Animation中3个类以及一个接口的总称,他的作用就是对给定的属性来计算当前动画的值,这个值是什么含义呢?简单理解
就是动画的状态比如你做一个淡入淡出的动画,假设动画时间2秒,那么每一时刻的动画的透明度就是通过这个接口来实现的,具体理解可以看后
面的例子再去领悟Interpolators是Property Animation中已经实现来的9个类以及一个接口的总称,那么他的具体作用是什么呢?Interpolators简称
插值器,用来计算时间的比例因子,举个例子吧,假如你要实现一个非线性的平移动画,那么你是要先加速平移然后减速平移,还是先匀速平移后
减速平移呢?Interpolators就是干这个事情的,android中以及实现了9个类了,分别是:
1)AccelerateDecelerateInterpolator:先加速再减速。 2)AccelerateInterpolator:一直加速。 3)AnticipateInterpolator:先往后一下,再嗖的一声一往无前。 4)AnticipateOvershootInterpolator:先往后一下,再一直往前超过终点,再往回收一下。 5)BounceInterpolator:最后像个小球弹几下。 6)CycleInterpolator:重复几次,感觉就是环形进度条那种,具体我还没试过。 7)DecelerateInterpolator:一直减速。 8)LinearInterpolator:线性,这个就是我们上面讲到的很均匀的了。 9)OvershootInterpolator:到了终点之后,超过一点,再往回走。有个参数可以定义,超过的力度。
Evaluators和Interpolators都提供了接口TypeEvaluator和TimeInterpolator来供我们自定义各种状态。下面我们就来实现一个自定义的非线性动画
他实现了按钮按照贝塞尔曲线运动
public class AnimatorInterpolatorsAndEvaluator extends Activity implements OnClickListener{ ValueAnimator valueAnimator; Button button; float width,height; ObjectAnimator object; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_animator_interpolators_and_evaluator); button = (Button)findViewById(R.id.button); button.setOnClickListener(this); DisplayMetrics metircs = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metircs); width = metircs.widthPixels; height = metircs.heightPixels; valueAnimator = ValueAnimator.ofObject(new BezierEvaluator(), new PointF(0,0),new PointF(width,height)); valueAnimator.setDuration(2000); valueAnimator.setInterpolator(new DecelerateInterpolator());//使用Interpolator对象,能够改变动画的运行速度 valueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { PointF pointF = (PointF)animation.getAnimatedValue(); button.setX(pointF.x); button.setY(pointF.y); } }); valueAnimator.setTarget(button); valueAnimator.setRepeatCount(1); valueAnimator.setRepeatMode(Animation.REVERSE); } public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; } class BezierEvaluator implements TypeEvaluator<PointF>{ @Override public PointF evaluate(float fraction, PointF startValue, PointF endValue) { final float t = fraction; float oneMinusT = 1.0f - t; PointF point = new PointF(); PointF point0 = (PointF)startValue; PointF point1 = new PointF(); point1.set(width, 0); PointF point2 = new PointF(); point2.set(0, height); PointF point3 = (PointF)endValue; point.x = oneMinusT * oneMinusT * oneMinusT * (point0.x) + 3 * oneMinusT * oneMinusT * t * (point1.x) + 3 * oneMinusT * t * t * (point2.x) + t * t * t * (point3.x); point.y = oneMinusT * oneMinusT * oneMinusT * (point0.y) + 3 * oneMinusT * oneMinusT * t * (point1.y) + 3 * oneMinusT * t * t * (point2.y) + t * t * t * (point3.y); return point; } } @Override public void onClick(View v) { if(v.getId() == R.id.button){ if(valueAnimator!=null){ valueAnimator.start(); } } } }
图我不贴了,直接复制上面的代码就行了。
他的逻辑是这样的,首先我实现了TypeEvaluator接口,他实现了贝塞尔曲线是的每一点坐标值,然后将这个值返回,第二我使用了android中
一个自定义的插值器,第三利用ValueAnimator.ofObject方法创建ValueAnimator对象,将插值器对象以及Evaluator对象设置进去,第四实现
AnimatorUpdateListener接口,实现其onAnimationUpdate方法,在这个方法中将每一点的坐标值设置给按钮,然后让按钮添加动画监听。
以上就是Property Animation的全部详解了。
参考链接:http://blog.csdn.net/linmiansheng/article/details/18763987