1. Android 中动画的分类
View 动画
- View 动画通过对场景里的对象不断做图像变换(平移、缩放、旋转、透明度)从而产生动画效果
- View 动画是一种渐进式动画,并且支持自定义
帧动画
- 帧动画通过顺序播放一系列图像从而产生动画效果,可以简单理解为图片切换动画
- 很显然,如果图片过多过大就会导致 OOM。帧动画也属于 View 动画的一种,只不过和平移、旋转等常见的 View 动画在表现形式上略有不同
属性动画
- 属性动画通过动态改变对象的属性从而达到动画效果
- 属性动画为 API 11 版本的新特性,在低版本无法直接使用属性动画
2. View 动画的分类
名称 | 标签 | 子类 | 效果 |
---|---|---|---|
平移动画 | <translate |
TranslateAnimation |
移动 View |
缩放动画 | <scale> |
ScaleAnimation |
缩放 View |
旋转动画 | <rotate> |
RotateAnimation |
旋转 View |
透明度动画 | <alpha> |
AlphaAnimation |
改变 View 的透明度 |
3. View 动画 XML 语法
1 |
|
View 动画既可以是单个动画,也可以由一系列动画组成
<set>
标签表示动画集合,对应 AnimationSet 类,它可以包含若干个动画,并且它的内部也是可以嵌套其他动画集合。两个属性含义如下:属性 含义 android:interpolator
表示动画集合所采用的插值器,插值器影响动画的速度,比如非匀速动画就需要通过插值器来控制动画的播放过程。这个属性可以不指定,默认为 @android:anim/accelerate_decelerate_interpolator
,即加速减速插值器android:shareInterpolator
表示集合中的动画是否和集合共享同一个插值器。如果集合不指定插值器,那么子动画就需要单独指定所需的插值器或者使用默认值 <translate>
标签:表示平移动画,对应 TranslateAnimation 类,它可以是一个 View 在水平和竖直方向完成平移的动画效果。其属性含义如下:属性 含义 android:fromXDelta
表示 x 的起始值,比如 0 android:toXDelta
表示 x 的结束值,比如 100 android:fromYDelta
表示 y 的起始值 android:toYDelta
表示 y 的结束值 <scale>
标签:表示缩放动画,对应 ScaleAnimation 类,它可以使 View 具有放大或缩小的动画效果。其属性含义如下:属性 含义 android:fromXScale
水平方向缩放的起始值,比如 0.5 android:toXScale
水平方向缩放的结束值,比如 1.2 android:fromYScale
竖直方向缩放的起始值 android:toYScale
竖直方向缩放的结束值 android:pivotX
缩放的轴点的 x 坐标,它会影响缩放的效果 android:pivotY
缩放的轴点的 y 坐标,它会影响缩放的效果 - 轴点:默认情况下轴点是 View 的中心点,此时在水平方向进行缩放会导致 View 向左右两个方向同时进行缩放。如果把轴点设为 View 的右边界,那么 View 就只会向左边进行缩放,反之则向右边进行缩放
<rotate>
标签:表示旋转动画,对应于 RotateAnimation 类,它可以使 View 具有旋转的动画效果。其属性含义如下:属性 含义 android:fromDegrees
旋转开始的角度,比如 0 android:toDegrees
旋转结束的角度,比如 180 android:pivotX
旋转的轴点的 x 坐标 android:pivotY
旋转的轴点的 y 坐标 - 轴点:在旋转动画中,轴点扮演着旋转轴的角色,即 View 是围绕着轴点进行旋转的,默认情况下轴点为 View 的中心点
<alpha>
标签:表示透明度动画,对应 AlphaAnimation 类,它可以改变 View 的透明度。其属性含义如下:属性 含义 android:fromAlpha
表示透明度的起始值,比如 0.1 android:toAlpha
表示透明度的结束值,比如 1
View 动画还有一些常用的属性,如下:
属性 含义 android:duration
动画的持续时间 android:fillAfter
动画结束以后 View 是否停留在结束位置 通过 Animation 的
setAnimationListener()
方法可以给 View 动画添加过程监听。接口如下:1
2
3
4
5public static interface AnimationListener {
void onAnimationStart(Animation animation);
void onAnimationEnd(Animation animation);
void onAnimationRepeat(Animation animation);
}
4. 自定义 View 动画
简单的方面,派生一种新动画只需要继承 Animation 这个抽象类,然后重写
initialize()
和applyTransformation()
方法。在initialize()
方法中做一些初始化工作,在applyTransformation()
方法中进行相应的矩阵变换即可,很多时候需要采用 Camera 来简化矩阵变换的过程复杂的方面,自定义 View 动画的过程主要是矩阵变换的过程,矩阵变换涉及到数学上的概念和操作
Demo:
1
2
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
44
45
46
47
48
49// 来自于 Android 的 ApiDemos 中的一个自定义 View 动画 Rotate3dAnimation(可以围绕 y 轴旋转并且同时沿着 z 轴平移从而实现一种类似于 3D 的效果)
public class Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if(mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
1. 1. 1. 1. matrix.postTranslate(centerX, centerY);
}
}- 实际开发中很少用到自定义 View 动画
5. 帧动画
帧动画是顺序播放一组预先定义好的图片,类似于电影播放
系统提供了类 AnimationDrawable 来使用帧动画
Demo:
1
2
3
4
5
6
7
8
9// 通过 XML 定义一个 AnimationDrawable
// res/drawable/frame_animation.xml
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/image1" android:duration="500" />
<item android:drawable="@drawable/image2" android:duration="500" />
<item android:drawable="@drawable/image3" android:duration="500" />
</animation-list>1
2
3
4
5// 设置并使用 AnimationDrawable
Button mButton = (Button) findViewById(R.id.button1);
mButton.setBackgroundResource(R.drawable.frame_animation);
AnimationDrawable drawable = (AnimationDrawable) mButton.getBackground();
drawable.start();- 帧动画的使用比较简单,但比较容易引起 OOM,所以在使用帧动画时应尽量避免使用过多尺寸较大的图片