标签: propertyanimation | 分类:android应用技巧 |
3.0以前,android支持两种动画模式,tween animation,frameanimation,在android3.0中又引入了一个新的动画系统:propertyanimation,这三种动画模式在SDK中被称为property animation,view animation,drawableanimation。
参考:http://www.open-open.com/lib/view/open1329994048671.html
关于Property Animation的用法及总结
首先我们要先了解关于View在3.0之后引入的几个新的属性,并设置了其getter和setter方法:
1)translationX 和translationY:这两个属性控制了View所处的位置,它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。
2)rotation, rotationX 和rotationY:控制View绕着轴点(pivotX和pivotY)旋转。
3)scaleX 和 scaleY:控制View基于pivotX和pivotY的缩放。
4)pivotX 和 pivotY:旋转的轴点和缩放的基准点,默认是View的中心点。
5)x 和y:描述了view在其父容器中的最终位置,是左上角左标和偏移量(translationX,translationY)的和。
6)aplha:透明度,1是完全不透明,0是完全透明。
照例,先上效果Gif,然后再来讲解一下各种效果的实现。
同样的,在Property Animation机制中,同样可以通过XML 或者直接在Java中来定义我们的动画效果。
XML中定义动画效果
比如上面展示中ScaleX 按钮,其效果是在 res/animator/scalex.xml 中定义的,在这里也要说明一下,定义在animator中不是必须的,但是是android推荐的,因为在eclipse开发中,ADT插件(ADT 11.0.0+)只会去搜寻res/animator 这个路径,如果不是定义在这个文件夹里面,我们在开发的时候,就没法利用ADT的布局工具了。
android:duration="2000" android:propertyname="scaleX"android:repeatcount="1" android:repeatmode="reverse"android:valuefrom="1.0" android:valueto="2.0"xmlns:android="http://schemas.android.com/apk/res/android">
在XML中要利用objectAnimator来定义我们的某个属性的效果,所以:
1)propertyName当然是一定要的啦,理论上这个属性的值可以是对象中的任何有get/set方法的属性,不过我们这里是对View来说,所以一般而言,就是上面新加的那几种新属性了。
2)duration 持续时间
3)valueFrom 和valueTo:这就是动画开始和结束时,这个属性相对应的值了,如果我们是缩放的话,当然就是倍数了,如果是平移(Translation)的话,那么就是距离了。
4)repeatCount 和 repeatMode:这两个和View Animation 中是一样的,就不多说了。
在xml中定义好了之后,接下来就要在Java中调用了,如下:
Button btnScaleX =(Button)findViewById(R.id.buttonScaleX);
btnScaleX.setOnClickListener(this);
scaleXAnimator =(ObjectAnimator)AnimatorInflater.loadAnimator(this,R.animator.scalex);
scaleXAnimator.setTarget(btnScaleX);
...
public void onClick(View v) {
switch(v.getId()){
case R.id.buttonScaleX:
scaleXAnimator.start();
break;
...
1)当然,首先要找到我们动画的对象了,在demo中就是那个scaleX的button了。
2)利用AnimationInflater类的loadAnimator方法来获取我们的ObjectAnimator对象
3)利用setTarget(View)方法来设置这个动画应用的对象,在这里就是我们的按钮了。
4)触发动画效果,就是调用其start方法了。
当动画效果开始后,我们发现它就只是在x方向上变大,肿了,那我们要在Y方向上怎么办,在XML中一个ObjectAnimator只能对应于一个属性,所以下面就是Set的展现了,跟ViewAnimation一样,set也是将几个效果给弄在一起,一次性执行也行,顺序执行也行,只要设置其ordering属性就好。
第二个按钮scale,就是在X方向上和Y方向上同时进行的,其定义如下:
而在Java中呢,这个xml对应的对象已经不是ObjectAnimator了,而是AnimatorSet了,其代码如下:
Button btnScale = (Button)findViewById(R.id.buttonScale);
btnScale.setOnClickListener(this);
animatorScaleSet = (AnimatorSet)AnimatorInflater.loadAnimator(this,R.animator.scale);
animatorScaleSet.setTarget(btnScale);
Java中定义动画效果
我们也可以直接在java中创建OjbectAnimator和AnimatorSet对象,并设置对应的参数和属性,如:
Set:
Button buttonSet = (Button) findViewById(R.id.buttonSet);
buttonSet.setOnClickListener(this);
animationSet = new AnimatorSet();
animationSet.playTogether(
ObjectAnimator.ofFloat(buttonSet, alpha, 1,0,1),
ObjectAnimator.ofFloat(buttonSet, translationX, 0f,400f,0f),
ObjectAnimator.ofFloat(buttonSet, rotation, 0,180,360)
);
animationSet.setDuration(1000);
animationSet.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator arg0) {}
@Override
public void onAnimationRepeat(Animator arg0) {}
@Override
public void onAnimationEnd(Animator arg0) {}
@Override
public void onAnimationCancel(Animator arg0) {}
});
1)我们先通过ObjectAnimator的工厂方法创建几个ObjectAnimator:
1.1)target:动画效果的实施对象,也就是demo中的set按钮。
1.2)propertyName:对应的属性,如alpha,translationX等等。
1.3)values:这是一组值,就是由什么值变动到另外一个什么值,再到什么什么值。。。之类的。
* @param target The object whose property is to be animated.This object should
* have a public method on it called setName()
, wherename
is
* the value of the propertyName
parameter.
* @param propertyName The name of the property beinganimated.
* @param values A set of values that the animation will animatebetween over time.
* @return An ObjectAnimator object that is set up to animatebetween the given values.
*/
public static ObjectAnimator ofFloat(Object target, StringpropertyName, float... values) {
ObjectAnimator anim = new ObjectAnimator(target,propertyName);
anim.setFloatValues(values);
return anim;
}
2)然后通过 AnimatorSet的playTogether方法或者playAfter,playBefore等方法将其加入到set中,如果不加入到set的话,就是对
3)给set设置相对应的如duration之类的属性。
4)我们还能够给Animator添加一个Listener,让它能够对Animator的几个关键点进行响应,分别是开始,结束,重复,取消时的响应函数,在这里有一点要注意的就是:
4.1)如果添加的是 AnimatorListener,则其四个函数都要实现
4.2)我们也可以添加AnimatorListenerAdapter,它是以AnimatorListener的封装,实现了上面的几个空方法,我们只需要实现我们想要的方法就好了,比如:
new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator){
final Button button = (Button)findViewById(R.id.buttonViewPropAnimator);
button.animate().alpha(1).translationX(0f).start();
}
})
5)最后在onClick事件中调用其start方法。
不过在Java中,如果要实现一个对象不同属性的动画效果,除了Set,我们还可以利用PropertyValuesHolder和ViewPropertyAnimator对象来实现,具体做法如下:
PropertyValuesHolder
PropertyValuesHolder pvhX =PropertyValuesHolder.ofFloat(translationX,0f,300f);
PropertyValuesHolder pvhY =PropertyValuesHolder.ofFloat(translationY,0f,300f);
translateAnimator =ObjectAnimator.ofPropertyValuesHolder(buttonProValHolder,pvhX,pvhY);
translateAnimator.setDuration(2000);
1)我们可以通过 PropertyValuesHolder类的工厂方法ofInt,ofFloat等方法,让它能够Hold住对应property的value。
2)在利用ObjectAnimator的ofPropertyValuesHolder方法时,再将我们上面定义的propertyValuesHolder给传进去,定义出一个objectAnimator。
3)设置objectAnimator对应的属性,调用其Start方法就行。
ViewPropertyAnimator
也可以通过ViewPropertyAnimator类来实现,如下:
case R.id.buttonViewPropAnimator:
v.animate().translationX(100f).alpha(0).setListener(newAnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator){
final Button button = (Button)findViewById(R.id.buttonViewPropAnimator);
button.animate().alpha(1).translationX(0f).start();
}
}).start();
1)先利用view的animate()方法返回一个ViewPropertyAnimator对象,然后调用其translationX,alpha等方法,也可以给其添加listener。
2)最后调用其start方法即可。
关于ValueAnimator
从上面的代码中,我们可以发现,我们好像都是在用ObjectAnimator对象,那么ValueAnimator类呢?其实ObjectAnimator是ValueAnimator的一个子类,是比较常用的一个类。但是有时候如果ObjectAnimator不能满足我们的需求了,那么我们就要用ValueAnimator类了。但是我们留到下一篇文章讲PropertyAnimation的工作原理的时候再讲吧。 (Tips.其实demo中已经有一个ValueAnimator的实现了,各位可以先看一下)。
源代码请点击(请记住,上述属性是3.0后才支持的!!!)