转载请注明出处:http://blog.csdn.net/fishle123/article/details/50668189
Android提供三种形式动画:视图动画,帧动画,属性动画。其中属性动画的功能最强大,在Android 3.0中开始引入。本文介绍视图动画和帧动画的使用技巧。
Android的视图动画可以完成一系列的补间动画(Tween Animation),如平移,缩放,旋转,透明度变化等。视图动画是针对View的内容(content),因此,当View发生视图动画后,其响应事件的位置还是在动画之前的地方,视图动画仅仅改变的是View的内容的展示(如针对Button的平移动画,将Button的中心从A点移动到B点,动画完成后Button在B点显示,但如果要点击Button,还是得点A点区域,而不是点B点区域)。Android提供两种方式来定义动画:XML和Android Code(写代码的形式),推荐使用XML方式,因为可读性更好。下面分别介绍这两种视图动画的使用:
XML定义视图动画的语法如下:
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
<alpha>, <scale>, <translate>, <rotate>四个标签分别对应透明度、缩放、平移、旋转四种形式的视图动画,<set>用来定义一组或多组动画,它们分别对应AlphaAnimation,ScaleAnimation,TranslateAnimation,RotateAnimation,AnimationSet五个类。下面介绍几个重要的属性:
<set>标签
1)android:interpolator----动画集合使用的差值器,如线性差值器(如平移动画中X坐标随时间线性变化),默认为@android:anim/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%),表示相对于element的width,如10%表示偏移量为width的10%,取值范围-100%--100%。如果是10%p,表示偏移量为parent父窗口的width的10%;
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%表示位置相对于Object的width的10%,10%p表示Object的parent的width的10%;
4)android:pivotY----float或百分比,旋转的中心的y坐标。取值与pivotX类似,50%表示中心位置。
下面给出一个例子:
在res目录下新建一个文件夹anim,然后新建一个xml,文件名为tween_anim.xml,内容如下:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false" android:fillAfter="true" > <alpha android:duration="700" android:fromAlpha="0.2" android:toAlpha="1" android:interpolator="@android:anim/accelerate_decelerate_interpolator" /> <set android:interpolator="@android:anim/decelerate_interpolator" > <scale android:duration="4000" android:fromXScale="1.4" android:fromYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:toXScale="2" android:toYScale="2" /> <rotate android:duration="4000" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="-45" /> <translate android:fromXDelta="0" android:toXDelta="200" android:duration="4000" android:fromYDelta="0" android:toYDelta="200"/> </set> </set>
这样就完成了一个视图动画的定义,然后在MainActivity中使用这个动画:
mTextView = (TextView)findViewById(R.id.textView1);
mAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim);
mTextView.startAnimation(mAnimation);
效果如下:
上面有提到Android提供了AlphaAnimation,ScaleAnimation,TranslateAnimation,RotateAnimation,AnimationSet五个类来帮助我们实现视图动画,它们分别对应透明度东湖,缩放动画,平移动画,旋转动画和动画集合。上面的动画效果如果使用代码的方式,可以如下实现:
AlphaAnimation al = new AlphaAnimation(0.2f, 1); al.setDuration(700); al.setInterpolator(new AccelerateDecelerateInterpolator()); ScaleAnimation sc = new ScaleAnimation(1.4f, 2f,0.6f, 2f, Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF, 0.5f); RotateAnimation ro = new RotateAnimation(0, -45, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); TranslateAnimation tr= new TranslateAnimation(0, 200, 0, 200); boolean shareInterpolator0 = true; AnimationSet set0 = new AnimationSet(shareInterpolator0); set0.setDuration(4000); set0.setInterpolator(new DecelerateInterpolator()); set0.addAnimation(sc); set0.addAnimation(ro); set0.addAnimation(tr); boolean shareInterpolator1 = false; AnimationSet set1 = new AnimationSet(shareInterpolator1); set1.addAnimation(al); set1.addAnimation(set0); view.startAnimation(set1);
对于Animation事件,Android提供了Animation.AnimationListener接口来接收事件通知。如果监听相应的事件,代码如下:
animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub } });
帧动画也称为Drawable Animation,帧动画用来播放一系列的Drawable,就像放电影一样。与视图动画不同,Android提供了AnimationDrawable类来使用帧动画,它是Drawable的子类,同时实现了Animatable接口,所以也具有动画功能。同样的,帧动画也可以使用XML和code两种方式来实现,不过使用XML更直观,更简单,推荐使用XML方式。下面分别介绍两种实现方式。
XML定义帧动画语法如下:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot=["true" | "false"] > <item android:drawable="@[package:]drawable/drawable_resource_name" android:duration="integer" /> </animation-list>
<animation-list>
标签定义一个帧动画,它是帧动画的根节点。包含一个或多个<item>
1)android:oneshot----boolean类型,true表示只播放一次动画,false表示循环播放动画。
<item>
定义一帧动画,必须作为<animation-list>的子节点。
1)android:drawable----drawable资源,即要在这一帧中展示的内容;
2)android:duration----integer,该帧展示的时间,单位是毫秒milliseconds。
下面给出一个例子:
先在res/anim目录下新建color_show.xml,然后在该文件中定义帧动画:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" > <item android:drawable="@drawable/frame0" android:duration="1000"/> <item android:drawable="@drawable/frame1" android:duration="1000"/> <item android:drawable="@drawable/frame2" android:duration="1000"/> </animation-list>
然后在MainActivity中使用这个动画:
ImageView imageView = (ImageView)findViewById(R.id.imageView); imageView.setBackgroundResource(R.drawable.color_show); AnimationDrawable drawable = (AnimationDrawable)imageView.getBackground(); drawable.start();
动画效果如下图:
帧动画比较容易引起OOM,所以在使用帧动画的时候应该尽量避免使用太多尺寸较大的图片。
与视图动画不同,Android提供了AnimationDrawable类来使用帧动画,它并不是Animation的子类,而是Drawable的子类,同时实现了Animatable接口,所以也具有动画功能。同样的,上面的动画效果如果使用Android code方式,可以如下实现:
Resources resources = getResources(); Drawable frame0= resources.getDrawable(R.drawable.frame0); Drawable frame1=resources.getDrawable(R.drawable.frame1); Drawable frame2=resources.getDrawable(R.drawable.frame2); AnimationDrawable drawable = new AnimationDrawable(); int duration = 1000; drawable.addFrame(frame0, duration); drawable.addFrame(frame1, duration); drawable.addFrame(frame2, duration); imageView.setBackgroundDrawble(drawable);//view.setBackground(drawable); drawable.setOneShot(false); drawable.start();
有一点需要注意,AnimationDrawable的start方法不能在Activity的onCreate方法中调用,因为这个时候AnimationDrawable还没有完全attached到window上(可能还没有调用ViewManager的addView来将Decoriew添加到PhoneWindow)。如果不需要任何交互就立即开始播放动画,可以在Activity的onWindowFocusChanged()方法中调用AnimationDrawable的start方法开始播放。
到此为止,视图动画和帧动画的使用总结完毕。这里需要记住的是:视图动画是针对View的内容(content),因此,当View发生视图动画后,其响应事件的位置还是在动画之前的地方,视图动画仅仅改变的是View的内容的展示。