Android动画学习-视图动画&属性动画(二)

文章参考:http://blog.csdn.net/linmiansheng/article/details/18716841

 上一篇文章讲到 View Animation 只能作用在View 上,而对那些不是View的对象是不起作用的,而Property Animation则不然,它是对一切对象的一切属性都起作用,只要这个属性有对应的get/set方法。不过话虽然如此说,我个人觉得,动画效果如果我们看不到的话,那有啥意思,而能够让我们看得到的对象,基本上都是View对象,或者间接转化为View对象的。所以,我们还是来关注怎么利用Property Animation来实现View的动画效果吧。


新的属性

首先我们要先了解关于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是完全透明。


同样的,在Property Animation机制中,同样可以通过XML 或者直接在Java中来定义我们的动画效果。

XML中定义动画效果

比如上面展示中ScaleX 按钮,其效果是在 res/animator/scalex.xml 中定义的,在这里也要说明一下,定义在 animator中不是必须的,但是是android推荐的,因为在eclipse开发中,ADT插件(ADT 11.0.0+)只会去搜寻 res/animator 这个路径,如果不是定义在这个文件夹里面,我们在开发的时候,就没法利用ADT的布局工具了。

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <objectAnimator   
  3.     xmlns:android="http://schemas.android.com/apk/res/android"   
  4.     android:propertyName="scaleX"  
  5.     android:duration="2000"  
  6.     android:valueFrom="1.0"  
  7.     android:valueTo="2.0"  
  8.     android:repeatCount="1"  
  9.     android:repeatMode="reverse">  
  10. </objectAnimator>  
在XML中要利用objectAnimator来定义我们的某个属性的效果,所以:

1)propertyName 当然是一定要的啦,理论上这个属性的值可以是对象中的任何有get/set方法的属性,不过我们这里是对View来说,所以一般而言,就是上面新加的那几种新属性了。

2)duration 持续时间

3)valueFrom 和 valueTo:这就是动画开始和结束时,这个属性相对应的值了,如果我们是缩放的话,当然就是倍数了,如果是平移(Translation)的话,那么就是距离了。

4)repeatCount 和 repeatMode:这两个和View Animation 中是一样的,就不多说了。

在xml中定义好了之后,接下来就要在Java中调用了,如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Button btnScaleX = (Button)findViewById(R.id.buttonScaleX);  
  2. btnScaleX.setOnClickListener(this);  
  3. scaleXAnimator = (ObjectAnimator)AnimatorInflater.loadAnimator(this, R.animator.scalex);  
  4. scaleXAnimator.setTarget(btnScaleX);  
  5. ...  
  6. public void onClick(View v) {          
  7.     switch(v.getId()){                    
  8.         case R.id.buttonScaleX:  
  9.             scaleXAnimator.start();  
  10.             break;                
  11.     ...      

1)当然,首先要找到我们动画的对象了,在demo中就是那个scaleX的button了。

2)利用AnimationInflater类的loadAnimator方法来获取我们的ObjectAnimator对象

3)利用setTarget(View)方法来设置这个动画应用的对象,在这里就是我们的按钮了。

4)触发动画效果,就是调用其start方法了。

当动画效果开始后,我们发现它就只是在x方向上变大,肿了,那我们要在Y方向上怎么办,在XML中一个ObjectAnimator只能对应于一个属性,所以下面就是Set的展现了,跟View Animation一样,set也是将几个效果给弄在一起,一次性执行也行,顺序执行也行,只要设置其ordering属性就好。

第二个按钮scale,就是在X方向上和Y方向上同时进行的,其定义如下:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android"   
  3.     android:ordering="together">  
  4.     <objectAnimator  
  5.         android:duration="2000"  
  6.         android:propertyName="scaleX"  
  7.         android:repeatCount="1"  
  8.         android:repeatMode="reverse"  
  9.         android:valueFrom="1.0"  
  10.         android:valueTo="2.0" >  
  11.     </objectAnimator>  
  12.     <objectAnimator  
  13.         android:duration="2000"  
  14.         android:propertyName="scaleY"  
  15.         android:repeatCount="1"  
  16.         android:repeatMode="reverse"  
  17.         android:valueFrom="1.0"  
  18.         android:valueTo="2.0" >  
  19.     </objectAnimator>  
  20. </set>  
而在Java中呢,这个xml对应的对象已经不是ObjectAnimator了,而是AnimatorSet了,其代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Button btnScale = (Button)findViewById(R.id.buttonScale);  
  2. btnScale.setOnClickListener(this);  
  3. animatorScaleSet = (AnimatorSet)AnimatorInflater.loadAnimator(this, R.animator.scale);  
  4. animatorScaleSet.setTarget(btnScale);  

Java中定义动画效果

我们也可以直接在java中创建OjbectAnimator和AnimatorSet对象,并设置对应的参数和属性,如:

Set

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Button buttonSet = (Button) findViewById(R.id.buttonSet);  
  2. buttonSet.setOnClickListener(this);  
  3. animationSet = new AnimatorSet();  
  4. animationSet.playTogether(  
  5.         ObjectAnimator.ofFloat(buttonSet, "alpha"1,0,1),  
  6.         ObjectAnimator.ofFloat(buttonSet, "translationX", 0f,400f,0f),  
  7.         ObjectAnimator.ofFloat(buttonSet, "rotation"0,180,360)  
  8.         );  
  9. animationSet.setDuration(1000);  
  10. animationSet.addListener(new AnimatorListener() {             
  11.     @Override  
  12.     public void onAnimationStart(Animator arg0) {}  
  13.     @Override  
  14.     public void onAnimationRepeat(Animator arg0) {}           
  15.     @Override  
  16.     public void onAnimationEnd(Animator arg0) {}              
  17.     @Override  
  18.     public void onAnimationCancel(Animator arg0) {}           
  19. });  

1)我们先通过ObjectAnimator的工厂方法创建几个ObjectAnimator:

1.1)target:动画效果的实施对象,也就是demo中的set按钮。

1.2)propertyName:对应的属性,如alpha,translationX等等。

1.3)values:这是一组值,就是由什么值变动到另外一个什么值,再到什么什么值。。。之类的。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @param target The object whose property is to be animated. This object should  
  2. * have a public method on it called <code>setName()</code>, where <code>name</code> is  
  3. * the value of the <code>propertyName</code> parameter.  
  4. @param propertyName The name of the property being animated.  
  5. @param values A set of values that the animation will animate between over time.  
  6. @return An ObjectAnimator object that is set up to animate between the given values.  
  7. */  
  8. ublic static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {  
  9.    ObjectAnimator anim = new ObjectAnimator(target, propertyName);  
  10.    anim.setFloatValues(values);  
  11.    return anim;  
2)然后通过 AnimatorSet的playTogether方法或者playAfter, playBefore等方法将其加入到set中

3)给set设置相对应的如duration之类的属性

4)我们还能够给Animator添加一个Listener,让它能够对Animator的几个关键点进行响应,分别是开始,结束,重复,取消时的响应函数,在这里有一点要注意的就是:

4.1)如果添加的是 AnimatorListener,则其四个函数都要实现

4.2)我们也可以添加 AnimatorListenerAdapter,它是以AnimatorListener的封装,实现了上面的几个空方法,我们只需要实现我们想要的方法就好了,比如:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. new AnimatorListenerAdapter() {  
  2.     @Override  
  3.     public void onAnimationEnd(Animator animator){  
  4.         final Button button = (Button) findViewById(R.id.buttonViewPropAnimator);  
  5.         button.animate().alpha(1).translationX(0f).start();  
  6.     }  
  7. })  
5)最后在onClick事件中调用其start方法。


不过在Java中,如果要实现一个对象不同属性的动画效果,除了Set,我们还可以利用PropertyValuesHolder和ViewPropertyAnimator对象来实现,具体做法如下:

PropertyValuesHolder

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("translationX",0f,300f);  
  2. PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("translationY",0f,300f);         
  3. translateAnimator = ObjectAnimator.ofPropertyValuesHolder(buttonProValHolder, pvhX,pvhY);  
  4. translateAnimator.setDuration(2000);  
1)我们可以通过 PropertyValuesHolder类的工厂方法ofInt, ofFloat等方法,让它能够Hold住对应property的value。
2)在利用ObjectAnimator的ofPropertyValuesHolder方法时,再将我们上面定义的propertyValuesHolder给传进去,定义出一个objectAnimator。
3)设置objectAnimator对应的属性,调用其Start方法就行。

ViewPropertyAnimator

也可以通过ViewPropertyAnimator类来实现,如下:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. case R.id.buttonViewPropAnimator:  
  2.     v.animate().translationX(100f).alpha(0).setListener(new AnimatorListenerAdapter() {  
  3.         @Override  
  4.         public void onAnimationEnd(Animator animator){  
  5.             final Button button = (Button) findViewById(R.id.buttonViewPropAnimator);  
  6.             button.animate().alpha(1).translationX(0f).start();  
  7.         }  
  8.     }).start(); 
1)先利用view的animate() 方法返回一个ViewPropertyAnimator对象,然后调用其translationX,alpha等方法,也可以给其添加listener。
2)最后调用其start方法即可。

关于ValueAnimator

从上面的代码中,我们可以发现,我们好像都是在用ObjectAnimator对象,那么ValueAnimator类呢?其实ObjectAnimator是ValueAnimator的一个子类,是比较常用的一个类。
但是有时候如果ObjectAnimator不能满足我们的需求了,那么我们就要用ValueAnimator类了。

P.S. 大家有没有发现,在View Animation中,当我们移动一个按钮到另外一个地方的时候,要响应按钮的点击事件的时候,我们必须在原来的位置点击,那么在Property Animation中呢,当然是不用啦,大家可以在demo中试试。

P.S. 大家有没有发现,PropertyAnimation基本上都是用animator,而不是用animation了呢?


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值