Android动画框架(一)----视图动画&帧动画

来源:互联网 发布:雷达回波数据 编辑:程序博客网 时间:2024/06/05 10:25

转载请注明出处:http://blog.csdn.net/fishle123/article/details/50668189

Android提供三种形式动画:视图动画,帧动画,属性动画。其中属性动画的功能最强大,在android 3.0中开始引入。本文介绍视图动画和帧动画的使用技巧。

1 视图动画(View Animation)

Android的视图动画可以完成一系列的补间动画(Tween Animation),如平移,缩放,旋转,透明度变化等。视图动画是针对View的内容(content),因此,当View发生视图动画后,其响应事件的位置还是在动画之前的地方,视图动画仅仅改变的是View的内容的展示(如针对Button的平移动画,将Button的中心从A点移动到B点,动画完成后Button在B点显示,但如果要点击Button,还是得点A点区域,而不是点B点区域)。Android提供两种方式来定义动画:XML和Android Code(写代码的形式),推荐使用XML方式,因为可读性更好。下面分别介绍这两种视图动画的使用:

1.1 XML方式

XML定义视图动画的语法如下:

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:interpolator="@[package:]anim/interpolator_resource"  
  3.     android:shareInterpolator=["true" | "false"] >  
  4. <alpha  
  5.         android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
  6.         android:fromAlpha="float"  
  7.         android:toAlpha="float" />  
  8.     <scale  
  9.         android:fromXScale="float"  
  10.         android:toXScale="float"  
  11.         android:fromYScale="float"  
  12.         android:toYScale="float"  
  13.         android:pivotX="float"  
  14.         android:pivotY="float" />  
  15.     <translate  
  16.         android:fromXDelta="float"  
  17.         android:toXDelta="float"  
  18.         android:fromYDelta="float"  
  19.         android:toYDelta="float" />  
  20.     <rotate  
  21.         android:fromDegrees="float"  
  22.         android:toDegrees="float"  
  23.         android:pivotX="float"  
  24.         android:pivotY="float" />  
  25.     <set>  
  26.         ...  
  27.     </set>  
  28. </set>  

<alpha>, <scale>, <translate>, <rotate>四个标签分别对应透明度、缩放、平移、旋转四种形式的视图动画,<set>用来定义一组或多组动画,它们分别对应AlphaAnimationScaleAnimationTranslateAnimationRotateAnimationAnimationSet五个类。下面介绍几个重要的属性:

<set>标签

1)android:interpolator----动画集合使用的差值器,如线性差值器(如平移动画中X坐标随时间线性变化),默认为@androidanim/accelerate_decelerate_interpolator,即加速减速差值器;

2)android:shareInterpolator----它的值是一个boolean值,表示集合中的动画是否共享同一个差值器。如果不共享同一个差值器,每个动画可以定义自己的使用的差值器。

系统提供的差值器如下表,当然我们也可以定义自己的差值器。

Interpolator class

Resource ID

AccelerateDecelerateInterpolator

@android:anim/accelerate_decelerate_interpolator

AccelerateInterpolator

@android:anim/accelerate_interpolator

AnticipateInterpolator

@android:anim/anticipate_interpolator

AnticipateOvershootInterpolator

@android:anim/anticipate_overshoot_interpolator

BounceInterpolator

@android:anim/bounce_interpolator

CycleInterpolator

@android:anim/cycle_interpolator

DecelerateInterpolator

@android:anim/decelerate_interpolator

LinearInterpolator

@android:anim/linear_interpolator

OvershootInterpolator

@android:anim/overshoot_interpolator

<alpha>标签

1)android:fromAlpha----float类型,表示透明度alpha的起始值,如0表示完全透明,1表示不透明;

2)android:toAlpha----float类型,表示透明度alpha的结束值。

<scale>标签

1)android:fromXScale---float类型,水平方向缩放起始值,1表示不做缩放;

2)android:toXScale----float类型,水平方向缩放结束值;

3)android:fromYScale----float类型,竖直方向缩放结束值;

4)android:toYScale----float类型,竖直方向缩放结束值;

5)android:pivotX----float类型,缩放的轴点的x坐标,默认为view的中心点;

6)android:pivotY----float类型,缩放的轴点y坐标,默认为view的中心点;

<translate>标签

1)android:fromXDelta----float或百分比,x方向的起始偏移量。如果是float类型,则偏移量以pixel为单位,是一个绝对值。如果是百分比(如10%),表示相对于elementwidth,如10%表示偏移量为width10%,取值范围-100%--100%。如果是10%p,表示偏移量为parent父窗口的width10%

2)android:toXDelta----float或百分比,x方向的结束偏移量,取值与fromXDelta类似;

3)android:fromYDelta----float或百分比,y方向的起始偏移量,取值与fromXDelta类似,但是百分比是相对于height

4)android:toYDelta----float或百分比,y方向的结束偏移量,取值与fromYDelta类似;

<rotate>标签

1)android:fromDegrees----float,旋转的起始角度,单位是degree

2)android:toDegrees----float,旋转的结束角度,单位是degree

3)android:pivotX----float或百分比,旋转的中心的x坐标。如果是float类型,相对于Object的左边界的距离,以pixel为单位,如5表示距离左边界5个像素的位置。如果是百分比,如10%表示位置相对于Objectwidth10%10%p表示Objectparentwidth10%

4)android:pivotY----float或百分比,旋转的中心的y坐标。取值与pivotX类似,50%表示中心位置。

下面给出一个例子:

res目录下新建一个文件夹anim,然后新建一个xml,文件名为tween_anim.xml,内容如下:

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:shareInterpolator="false"  
  4.     android:fillAfter="true" >  
  5.    
  6.     <alpha  
  7.         android:duration="700"  
  8.         android:fromAlpha="0.2"  
  9.         android:toAlpha="1"  
  10.         android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
  11.          
  12.         />  
  13.    
  14.     <set android:interpolator="@android:anim/decelerate_interpolator" >  
  15.         <scale  
  16.             android:duration="4000"  
  17.             android:fromXScale="1.4"  
  18.             android:fromYScale="0.6"  
  19.             android:pivotX="50%"  
  20.             android:pivotY="50%"  
  21.             android:toXScale="2"  
  22.             android:toYScale="2" />  
  23.    
  24.         <rotate  
  25.             android:duration="4000"  
  26.             android:fromDegrees="0"  
  27.             android:pivotX="50%"  
  28.             android:pivotY="50%"  
  29.             android:toDegrees="-45" />  
  30.         <translate  
  31.             android:fromXDelta="0"  
  32.             android:toXDelta="200"  
  33.             android:duration="4000"  
  34.             android:fromYDelta="0"  
  35.             android:toYDelta="200"/>  
  36.     </set>  
  37.    
  38. </set>  

这样就完成了一个视图动画的定义,然后在MainActivity中使用这个动画:

mTextView = (TextView)findViewById(R.id.textView1);

mAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim);

mTextView.startAnimation(mAnimation);

 

效果如下:

 

1.2 Android code方式

上面有提到Android提供了AlphaAnimationScaleAnimationTranslateAnimationRotateAnimationAnimationSet五个类来帮助我们实现视图动画,它们分别对应透明度东湖,缩放动画,平移动画,旋转动画和动画集合。上面的动画效果如果使用代码的方式,可以如下实现:

[java] view plain copy
  1. AlphaAnimation al = new AlphaAnimation(0.2f, 1);  
  2. al.setDuration(700);  
  3. al.setInterpolator(new AccelerateDecelerateInterpolator());  
  4. ScaleAnimation sc = new ScaleAnimation(1.4f, 2f,0.6f, 2f, Animation.RELATIVE_TO_SELF,0.5f,  
  5. Animation.RELATIVE_TO_SELF, 0.5f);  
  6. RotateAnimation ro = new RotateAnimation(0, -45, Animation.RELATIVE_TO_SELF, 0.5f,  
  7. Animation.RELATIVE_TO_SELF, 0.5f);  
  8. TranslateAnimation tr= new TranslateAnimation(02000200);  
  9. boolean shareInterpolator0 = true;  
  10. AnimationSet set0 = new AnimationSet(shareInterpolator0);  
  11. set0.setDuration(4000);  
  12. set0.setInterpolator(new DecelerateInterpolator());  
  13. set0.addAnimation(sc);  
  14. set0.addAnimation(ro);  
  15. set0.addAnimation(tr);  
  16. boolean shareInterpolator1 = false;  
  17. AnimationSet set1 = new AnimationSet(shareInterpolator1);  
  18. set1.addAnimation(al);  
  19. set1.addAnimation(set0);  
  20. view.startAnimation(set1);  

对于Animation事件,Android提供了Animation.AnimationListener接口来接收事件通知。如果监听相应的事件,代码如下:

[java] view plain copy
  1. animation.setAnimationListener(new Animation.AnimationListener() {  
  2. @Override  
  3. public void onAnimationStart(Animation animation) {  
  4. // TODO Auto-generated method stub  
  5. }  
  6. @Override  
  7. public void onAnimationRepeat(Animation animation) {  
  8. // TODO Auto-generated method stub  
  9. }  
  10. @Override  
  11. public void onAnimationEnd(Animation animation) {  
  12. // TODO Auto-generated method stub  
  13. }  
  14. });  

帧动画(FrameAnimation

帧动画也称为Drawable Animation,帧动画用来播放一系列的Drawable,就像放电影一样。与视图动画不同,Android提供了AnimationDrawable类来使用帧动画,它是Drawable的子类,同时实现了Animatable接口,所以也具有动画功能。同样的,帧动画也可以使用XMLcode两种方式来实现,不过使用XML更直观,更简单,推荐使用XML方式。下面分别介绍两种实现方式。

2.1 XML方式

XML定义帧动画语法如下:

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:oneshot=["true" | "false"] >  
  4.     <item  
  5.         android:drawable="@[package:]drawable/drawable_resource_name"  
  6.         android:duration="integer" />  
  7. </animation-list>  

<animation-list>

标签定义一个帧动画,它是帧动画的根节点。包含一个或多个<item>

1android:oneshot----boolean类型,true表示只播放一次动画,false表示循环播放动画。

<item>

定义一帧动画,必须作为<animation-list>的子节点。

1)android:drawable----drawable资源,即要在这一帧中展示的内容;

2)android:duration----integer,该帧展示的时间,单位是毫秒milliseconds

下面给出一个例子:

先在res/anim目录下新建color_show.xml,然后在该文件中定义帧动画:

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:oneshot="false" >  
  4.    
  5.     <item  
  6.         android:drawable="@drawable/frame0"  
  7.         android:duration="1000"/>  
  8.     <item  
  9.         android:drawable="@drawable/frame1"  
  10.         android:duration="1000"/>  
  11.     <item  
  12.         android:drawable="@drawable/frame2"  
  13.         android:duration="1000"/>  
  14.    
  15. </animation-list>  

然后在MainActivity中使用这个动画:

[java] view plain copy
  1. ImageView imageView = (ImageView)findViewById(R.id.imageView);  
  2. imageView.setBackgroundResource(R.drawable.color_show);  
  3. AnimationDrawable drawable = (AnimationDrawable)imageView.getBackground();  
  4. drawable.start();  

动画效果如下图:

 

帧动画比较容易引起OOM,所以在使用帧动画的时候应该尽量避免使用太多尺寸较大的图片。

2.2 Android code方式

与视图动画不同,Android提供了AnimationDrawable类来使用帧动画,它并不是Animation的子类,而是Drawable的子类,同时实现了Animatable接口,所以也具有动画功能。同样的,上面的动画效果如果使用Android code方式,可以如下实现:

[java] view plain copy
  1. Resources  resources = getResources();  
  2. Drawable frame0= resources.getDrawable(R.drawable.frame0);  
  3. Drawable frame1=resources.getDrawable(R.drawable.frame1);  
  4. Drawable frame2=resources.getDrawable(R.drawable.frame2);  
  5. AnimationDrawable drawable = new AnimationDrawable();  
  6. int duration = 1000;  
  7. drawable.addFrame(frame0, duration);  
  8. drawable.addFrame(frame1, duration);  
  9. drawable.addFrame(frame2, duration);  
  10. imageView.setBackgroundDrawble(drawable);//view.setBackground(drawable);  
  11. drawable.setOneShot(false);  
  12. drawable.start();  

有一点需要注意,AnimationDrawable的start方法不能在Activity的onCreate方法中调用,因为这个时候AnimationDrawable还没有完全attached到window上(可能还没有调用ViewManager的addView来将Decoriew添加到PhoneWindow)。如果不需要任何交互就立即开始播放动画,可以在Activity的onWindowFocusChanged()方法中调用AnimationDrawable的start方法开始播放。

总结

到此为止,视图动画和帧动画的使用总结完毕。这里需要记住的是:视图动画是针对View的内容(content),因此,当View发生视图动画后,其响应事件的位置还是在动画之前的地方,视图动画仅仅改变的是View的内容的展示。

如果大家对动画感兴趣,可以阅读我的动画相关的其他文章,看完这些文章相信大多数动画相关的问题都能解决了。

Android动画框架(二)----属性动画

Android动画框架(三)----布局动画&Activity过渡动画