一、引言
动画在移动App开发中的重要性不言而喻,通俗点讲,动画可以让我们的App界面不那么死板,可以带来酷炫的交互效果。动画是一种高级的用户反馈,对用户操作、选择结果的一种反馈,对程序执行过程的动态展示,也是对用户视觉和注意力的引导,帮助用户更好地理解App的功能设计。所以说,动画的意义远不止酷炫这一层面。那么我们有必要了解动画,并把动画应用到我们的项目中去。
二、动画介绍
在 Android开发中,涉及动画有:
其实经常使用的也就三种类型:
- 帧动画:也叫 Frame 动画或者Drawable 动画,其实可以划分到视图动画的类别,实现方式是将一些列的 Drawable 像幻灯片一样一个一个地显示
- 补间动画:也叫视图动画或者View 动画,主要是指 android.view.animation 包下面的一些类,只能被用来设置给 View,缺点是比如当控件移动之后,接收点击的控件的位置不会跟随移动,并且能够实现的效果只有移动、缩放、旋转和淡入淡出操作四种及其组合
- 属性动画:Property 动画主要是指 android.animation 包下面的一些类,这种动画可以设置给任何 Object,包括那些还没有渲染到屏幕上的对象。这种动画是可扩展的,可以让你自定义任何类型和属性的动画
三、帧动画
帧动画是一个比较简单的动画框架,原理就像播放幻灯片一样,传一组图片进去,然后一幅幅图片按序播放,可以设置每一张图片的播放时间,效果像gif动画。
帧动画可以通过xml创建,准备了一系列图片资源,并在 drawable 文件夹下面定义了动画资源 animation_run.xml:
<?xml version="1.0" encoding="utf-8"?>
<animation-run xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@mipmap/run_1" android:duration="150" />
<item android:drawable="@mipmap/run_2" android:duration="150" />
<item android:drawable="@mipmap/run_3" android:duration="150" />
<item android:drawable="@mipmap/run_4" android:duration="150" />
</animation-run>
其中,android:oneshot 属性为true,它将会在最后一帧停下来,如果设置为false这个动画将循环播放。
接着,我们在代码中使用该资源,并将其赋值给 ImageView。然后,我们从该控件中获取该 Drawable 并将其转换成 AnimationDrawable,随后我们调用它的 start() 方法就开启了 Drawable 动画:
ImageView image = (ImageView) findViewById(R.id.iv_run);
image.setImageResource(R.drawable.animation_run);
AnimationDrawable anim = (AnimationDrawable) image.getDrawable();
anim.start();
此外,我们可以调用该 Drawable 的 stop() 方法停止动画。
帧动画的注意事项:使用帧动画的时候要注意设置的图片不宜过多、过大,以防止因为内存不够而出现 OOM。
四、补间动画
补间动画是Android最早的动画框架,从Android1.0就开始提供。Tween动画使用简单,功能也不强,支持代码和xml两种方式编写动画。动画的四种变换效果对应Animation的四个子类:TranslateAnimation、ScaleAnimation、RotateAnimation、AlphaAnimation,这些动画可以通过XML来定义,也可以通过代码动态定义。
根据不同的动画效果,补间动画分为4种动画:
- 平移动画(Translate)
- 缩放动画(scale)
- 旋转动画(rotate)
- 透明度动画(alpha)
而实际中很多需求都需要同时使用平移、缩放、旋转 & 透明度4种动画,即组合动画,使用组合动画需要用到标签 < Set/>
在路径 res/anim 的文件夹里创建动画效果 view_animation.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<rotate android:fromDegrees="0"
android:toDegrees="359"
android:duration="1000"
android:repeatCount="1"
android:repeatMode="reverse"
android:pivotX="50%"
android:pivotY="50%"/>
</set>
LinearLayout layout = (LinearLayout)findViewById(R.id.layout_1);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
layout.startAnimation(animation);
补间动画使用起来简单,效果也比较流畅,但是缺点也是很明显,首先就是拓展性太差,只能写移动、缩放、旋转、渐变四种动画以及这四种动画的组合,不支持自定义View的拓展。
五、属性动画
属性动画是Android3.0版本推出的动画框架,其功能和拓展性都很强。它不仅能实现所有Tween动画的功能,还有很强的拓展性,根本原因是属性动画从本质上已经完全摆脱了控件,虽然我们大多数情况下使用属性动画都是给控件做动画,但是属性动画的底层只是一个数值发生器,和控件没有半毛钱关系。
示例代码如下:
ValueAnimator animator = ValueAnimator.ofFloat(0, 360);
animator.setDuration(1000);
animator.setInterpolator(new AccelerateInterpolator());
animator.setRepeatCount(1);
animator.setRepeatMode(ValueAnimator.REVERSE);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float value = (float)valueAnimator.getAnimatedValue();
imageView.setRotationY(rotate);
}
});
animator.start();
我们使用ValueAnimator产生一组0-360的数值序列,数值变化速率遵循AccelerateInterpolator函数,时间为1000毫秒,然后在回调函数里我们可以获取当前动画值value,然后调用imageView.setRotationY(value);这样就实现了imageView的旋转动画。
我们除了可以用来做动画,还可以用在任何你能想到的地方。比如我们有一个TextView显示金额,这个金额要动画地从0增加到2000,这就可以用ValueAnimator。
示例代码如下:
ValueAnimator animator = ValueAnimator.ofFloat(0, 2000);
animator.setDuration(1000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float value = (float)valueAnimator.getAnimatedValue();
textView.setText(String.valueOf(value));
}
});
animator.start();
六、总结
通过整理Android中的基本动画,了解每一种动画的原理、使用方法、应用场景、优缺点等,学会如何使用一个通用动画库来简化动画。