Android开发中基础动画技巧的应用
一、引言
我是先入门iOS的移动开发者,提到动画开发,iOS开发者很容易联想到3种方式,UIImageView的帧动画,UIView层的属性动画和CoreAnimation动画。Android中也有3种方式创建基础动画效果,分别为View Animation,Property Animation和Drawable Animation。由于Android开发的固有特点,其在进行动画编程时也支持使用代码和xml配置文件两种方式。本篇博客,将主要向大家介绍这3种创建Android动画方式的使用方法与可以做到的效果。
二、View Animation动画的应用
View Animation又被称为Tweened Animation,其应用于View视图变化的动画过渡效果。View Animation主要分为如下4类:
①.AlphaAnimation:透明度动画
②.RotateAnimation:旋转动画
③.ScaleAnimation:缩放动画
④.TranslateAnimation:位移动画
1.AlphaAnimation的应用
AlphaAnimation用于当视图透明度发生变化时展示过渡动画,可以渐隐也可以渐现。使用AlphaAnimation创建动画的核心代码如下:
| 12
 3
 4
 5
 6
 
 | AlphaAnimation alphaAnimation = new AlphaAnimation(1,0);
 
 alphaAnimation.setDuration(3000);
 
 animationImageView.startAnimation(alphaAnimation);
 
 | 

2.RotateAnimation的应用
RotateAnimation用于创建视图的旋转动画。其相比AlphaAnimation要复杂一些,在使用时,除了需要设置其动画的起始角度和最终角度外,还可以设置视图旋转时的参照位置,示例代码如下:
| 12
 3
 4
 5
 6
 
 | RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
 
 rotateAnimation.setDuration(3000);
 
 animationImageView.startAnimation(rotateAnimation);
 
 | 
这里使用了RotateAnimation类中最复杂的一个构造方法,其中需要传入6个参数,前两个参数分别为旋转动画的起始角度与终止角度,第3个参数为旋转参照点的x轴相对位置类型,第4个参数为参照点x轴位置,第5个和第6个参数分别为旋转参照点的y轴相对位置类型与y轴相对位置。
关于参照点的相对位置类型,Animation类中定义了几个常量供开发者选择使用,意义如下:
| 12
 3
 4
 5
 6
 
 | public static final int ABSOLUTE = 0;
 
 public static final int RELATIVE_TO_PARENT = 2;
 
 public static final int RELATIVE_TO_SELF = 1;
 
 | 
还有一点需要注意,如果选择的参照类型是RELATIVE_TO_SELF,则参照点的位置参数取值范围为0-1之间,代表的是相对于自身的位置比例,如果参照类型是RELATIVE_TO_PARENT,则参照点的位置参数取值范围为0-1之间,代表的是相对于父视图的位置比例,如果参照类型是ABSOLUTE,则参照点的位置参数取值为绝对坐标值,例如100,150,其代表了相对窗口视图的坐标位置。例如上面示例代码中,以视图本身为参照物,x、y轴位置都设置为0.5,则旋转动画以视图本身中心为旋转点,如果需要以视图右下角为旋转点,修改代码如下:
| 1
 | RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,1f,Animation.RELATIVE_TO_SELF,1f);
 | 

3.ScaleAnimation的应用
ScaleAnimation用于创建放大或者缩小的形变动画,示例代码如下:
| 12
 3
 4
 5
 6
 
 | ScaleAnimation scaleAnimation = new ScaleAnimation(1,2,1,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
 
 scaleAnimation.setDuration(3000);
 
 animationImageView.startAnimation(scaleAnimation);
 
 | 
上面示例代码中前4个参数分别设置缩放动画x轴方向的起始值、最终值和y轴方向的起始值、终止值。需要注意,这里的单位都是比例,1表示原视图尺寸,2表示原视图尺寸的2倍。这个方法后4个参数的意义是确定缩放参照点的位置,和RotateAniamtion构造方法中的参数意义一致。

4.TranslateAnimation的应用
TranslateAnimation用于创建位移动画,示例代码如下:
| 12
 3
 4
 5
 6
 
 | TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE,0,Animation.ABSOLUTE,100,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,1);
 
 translateAnimation.setDuration(3000);
 
 animationImageView.startAnimation(translateAnimation);
 
 | 
上面示例代码中使用的TranslateAnimation构造方法中的8个参数分别代表,起始位置的x轴参照点类型与起始位置的x轴值、终止位置的x轴参照点类型与终止位置的x轴值、起始位置的y轴参照点类型与起始位置的y轴值、终止位置的y轴参照点类型与终止位置的y轴值。
5.Animation类中的通用方法
上面介绍的4种动画实际上都是Animation类的子类,Animation类中封装了许多动画通用的方法,例如前面使用的设置动画执行时间的方法setDuration就是Animation类的方法,其中更多常用方法列举如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 
 | public void cancel();
 
 public void setInterpolator(Interpolator i);
 
 public void setStartOffset(long startOffset);
 
 public void setDuration(long durationMillis);
 
 public void restrictDuration(long durationMillis);
 
 public void scaleCurrentDuration(float scale);
 
 public void setStartTime(long startTimeMillis);
 
 
 
 
 
 
 public void setRepeatMode(int repeatMode);
 
 public void setRepeatCount(int repeatCount);
 
 public void setFillEnabled(boolean fillEnabled);
 
 public void setFillBefore(boolean fillBefore);
 
 public void setFillAfter(boolean fillAfter)
 
 
 
 
 
 
 
 public void setZAdjustment(int zAdjustment);
 
 public void setDetachWallpaper(boolean detachWallpaper);
 
 public boolean hasStarted();
 
 public boolean hasEnded();
 
 | 
上面列举的方法中,setInterpolator()方法很有意思,其可以设置动画执行的时间函数,例如是先快后慢还是先慢后快等等,这个方法需要传入一个Interpolator类型的参数,实际上使用时是通过Interpolator的子类来实现的,示例如下:
| 1
 | ranslateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
 | 
对于Interpolator参数开发者可以设置的子类及意义列举如下:
AccelerateDecelerateInterpolator:先加速后减速执行
AccelerateInterpolator:加速执行
AnticipateInterpolator:先后退执行一步后正向加速执行(类似弹簧效果)

 AnticipateOvershootInterpolator:先后退执行一步后加速执行到达极限后再前进一步后再回到极限(弹簧)

BounceInterpolator:动画执行到结尾后进行阻尼效果

CycleInterpolator:以正弦规则循环执行数次动画,这个类来构造时需要传入循环次数,如下:
| 1
 | new CycleInterpolator(3)
 | 
DecelerateInterpolator:减速执行动画
 FastOutLinearInInterpolator:基于贝塞尔曲线的速率变化
 FastOutSlowInInterpolator:基于贝塞尔曲线的速率变化
 LinearInterpolator:线性匀速执行
LinearOutSlowInInterpolator:基于贝塞尔曲线的速率变化
OvershootInterpolator:执行超出极限后在回退

PathInterpolator:自定义运动路径
6.实现对Animation动画状态的监听
Animation类中也定义了一个监听器协议,其中提供了对动画状态进行监听的方法,如下:
| 12
 3
 4
 5
 6
 7
 8
 
 | public interface AnimationListener {
 void onAnimationStart(Animation var1);
 
 void onAnimationEnd(Animation var1);
 
 void onAnimationRepeat(Animation var1);
 }
 
 | 
7.使用xml文件配置View Animation
上面介绍的全部是通过代码来创建View Animation动画,Android也支持使用xml文件来配置View Animation动画。
首先在Android Studio的res目录中创建一个动画文件目录,将其类型选择为anim,如下图所示:

在创建的目录中创建一个新的xml文件,在其中编写动画代码如下:
| 12
 3
 4
 
 | <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">
 <alpha android:fromAlpha="1" android:toAlpha="0" android:duration = "3000"/>
 </set>
 
 | 
在代码中,使用如下代码来加载xml配置的动画:
| 12
 3
 4
 
 | Animation animation = AnimationUtils.loadAnimation(this,R.anim.my_anmi);
 
 animationImageView.startAnimation(animation);
 
 | 
8.复合的View Animation
View Animation也支持进行复合动画的操作,如果使用xml配置复合动画,十分简单,只需要将要要复合的动画都配置进xml文件的set标签中即可,如下:
| 12
 3
 4
 5
 
 | <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">
 <alpha android:fromAlpha="1" android:toAlpha="0" android:duration = "3000"/>
 <scale android:fromXScale="1" android:toXScale="2" android:fromYScale="1" android:toYScale="2" android:duration="3000"/>
 </set>
 
 | 

如果要用代码创建复合动画,需要使用到AnimationSet类进行复合,示例如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | AnimationSet set = new AnimationSet(true);
 
 RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,1f,Animation.RELATIVE_TO_SELF,1f);
 ScaleAnimation scaleAnimation = new ScaleAnimation(1,2,1,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
 scaleAnimation.setDuration(3000);
 rotateAnimation.setDuration(3000);
 
 set.addAnimation(rotateAnimation);
 set.addAnimation(scaleAnimation);
 
 animationImageView.startAnimation(set);
 
 | 

三、Property Animation动画的应用
在前面介绍的View Animation动画体系中,虽然使用起来十分方便,但也有十分多的局限性,例如只能支持透明度,位置,缩放和旋转动画,并且在动画执行时,视图实际上并没有移动,如果需要做动画的是可以用户交互的按钮控件则会带来很多的不便。在Android3.0之后,系统推出了Property Animation动画,这种机制可以将对象任意属性的修改实现过渡动画效果。
1.ObjectAnimator动画的应用
ObjectAnimator是Property Animation动画体系中最简单易用的一种方式,开发者只需要设置要改变的属性值和一些动画参数即可使用,例如若要实现视图以y方向为轴进行旋转操作,使用 如下代码实现:
| 12
 3
 4
 5
 6
 
 | ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(animationImageView,"rotationY",0,360,0);
 
 objectAnimator.setDuration(3000);
 
 objectAnimator.start();
 
 | 
ObjectAnimator类的静态方法ofFloat()用于创建属性动画实例本身,与其类似的方法还有ofInt()与ofObject()。需要注意,这些方法第1个参数为要执行动画的视图,第2个参数为要发生动画改变的属性名,从第3个参数开始后面可以添加任意多个值,这些值代表了属性值改变的路径,例如上面示例代码表示将视图以y方向为轴从0°开始旋转到360°后再旋转回0°。

ObjectAnimator类继承自ValueAnimator,ValueAnimator类则更加灵活自由,其可以为自定义类的自定义属性做动画处理,后面会介绍,ValueAnimator类中提供了许多动画配置的方法,常用如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | public ValueAnimator setDuration(long duration);
 
 public void setStartDelay(long startDelay);
 
 public void setRepeatCount(int value);
 
 public void setRepeatMode(int value);
 
 public void setInterpolator(TimeInterpolator value);
 
 public void start();
 
 public void end();
 
 public void cancel();
 
 public void resume();
 
 public void pause();
 
 | 
需要注意,使用ObjectAnimator创建动画的属性必须实现set和get方法。
2.ValueAnimator实现更加灵活的自定义动画
ObjectAnimator是ValueAnimator的子类,可以理解,ValueAnimator要比ObjectAnimator更加灵活自由,其可以实现任意自定义属性的动画行为。示例代码如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | ValueAnimator valueAnimator = new ValueAnimator();
 
 valueAnimator.setFloatValues(0,200,100,300,0);
 
 valueAnimator.setDuration(6000);
 
 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 
 @Override
 public void onAnimationUpdate(ValueAnimator valueAnimator) {
 
 animationImageView.setX((Float) valueAnimator.getAnimatedValue());
 }
 });
 
 valueAnimator.start();
 
 | 
如果运行上面代码,可以看到视图在6s内从x坐标点为0的地方平移到200后再次回到100后再次移动到300最终回到原点0。
上面的示例代码只是演示了ValueAnimator的工作原理,开发者可以在onAnimationUpdate()方法中进行任意属性的修改。仅从上面演示代码并不能体现出ValueAnimator的强大之处,可以通过实现类似抛物线的动画来理解ValueAnimator的灵活之处,示例代码如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 | final ValueAnimator animator = new ValueAnimator();
 
 animator.setObjectValues(new Point(0,0),new Point(400,0));
 
 animator.setDuration(4000);
 
 animator.setInterpolator(new LinearInterpolator());
 
 animator.setEvaluator(new TypeEvaluator<Point>() {
 
 @Override
 public Point evaluate(float v, Point o,Point t1) {
 
 Point point = new Point();
 point.x = (int)((v*8)*100);
 point.y = (int)((v*60)*(v*60)/4);
 return point;
 }
 });
 
 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 @Override
 public void onAnimationUpdate(ValueAnimator valueAnimator) {
 
 animationImageView.setX(((Point)valueAnimator.getAnimatedValue()).x);
 animationImageView.setY(((Point)valueAnimator.getAnimatedValue()).y);
 }
 });
 
 animator.start();
 
 | 

需要注意,Property Animation与View Animation最大的不同在于View Animation只是展示视图的界面动画,它并没有真正改变视图的属性,而Property Animation是实实在在的改变了发生动画控件的属性。
3.Property Animation动画的监听
ValueAnimator对象可以使用addListener()方法来添加监听者,接口方法如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | public interface AnimatorListener {
 
 void onAnimationStart(Animator var1);
 
 void onAnimationEnd(Animator var1);
 
 void onAnimationCancel(Animator var1);
 
 void onAnimationRepeat(Animator var1);
 }
 
 | 
4.使用PropertyValuesHolder进行动画复合
对于Property Animation,开发者可以通过ValueAnimator实现自定义的复合动画,也可以使用PropertyValuesHolder进行属性动画的复合操作,示例如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("rotationY",0,360,90);
 
 PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("alpha",1,0,1);
 
 ObjectAnimator objectAnimation = ObjectAnimator.ofPropertyValuesHolder(animationImageView,holder,holder2);
 
 objectAnimation.setDuration(3000);
 objectAnimation.start();
 
 | 

三、Drawable Animation动画的应用
相比前两种动画模式,Drawable Animation动画要容易的多,其使用一组图像快速切换的原理来实现动画效果。
在Android Studio的drawable文件夹中添加一个animation文件,xml代码如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | <?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:drawable="@drawable/bird1" android:duration="200" />
 <item android:drawable="@drawable/bird2" android:duration="200" />
 <item android:drawable="@drawable/bird3" android:duration="200" />
 <item android:drawable="@drawable/bird4" android:duration="200" />
 <item android:drawable="@drawable/bird5" android:duration="200" />
 <item android:drawable="@drawable/bird6" android:duration="200" />
 <item android:drawable="@drawable/bird7" android:duration="200" />
 <item android:drawable="@drawable/bird8" android:duration="200" />
 </animation-list>
 
 | 
将需要展示动画的视图背景设置为这个drawable文件,示例如下:
| 12
 3
 4
 5
 
 | <ImageViewandroid:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:background="@drawable/anmi_draw_list"
 android:id="@+id/animatedImageView"/>
 
 | 
在需要开始动画时,调用如下代码即可:
| 12
 
 | ((AnimationDrawable)animationImageView.getBackground()).start();
 
 | 

专注技术,热爱生活,交流技术,也做朋友。
——珲少 QQ群:435043639