android动画之从源码角度分析动画原理

本文深入剖析了Android动画的工作机制,重点介绍了Animation类、Transformation类、Matrix类及Camera类的作用,并通过实例展示了如何使用Camera实现平移、旋转等动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

出处:http://www.2cto.com/kf/201412/362001.html

以前一直不懂android的动画机制,android系统是如何实现动画的,所以导致只会做一些android系统已经为我们封装好的动画即:AlphaAnimation, TranslateAnimation, ScaleAnimation,RotateAnimation以及这些动画混合起来使用,其实有android系统为我们提供的这几种动画是可以满足我们平时的基本需求了,但是要做一些高级的动画就是不可能的,比如3D动画,所以就看了一下android系统所带动画的源码,做了一些总结,下面就是我对动画的新认识。

1.最重要的类,Animation类,一个抽象类,是所有动画的基类,它定义了Animation的公共属性和方法,属性中最重要的是:AnimationListener和Transformation,动画监听器,监听动画的开始,执行过程,结束,可以实现一些自己的逻辑, Transformation是每一帧动画中包含的信息(平移,旋转,绽放,透明度)方法中最重要的是:

public boolean getTransformation(long currentTime, Transformation outTransformation);和 protected void applyTransformation(float interpolatedTime, Transformation t)。

第一个方法由系统调用,根据动画当前时间计算出此时的Transformation信息,不必重写此方法,第二个方法是我们必须重写的, 根据系统由第一个方法计算出的Transformation进行实际的动画实现。

2.由上面的Animation类,可以知道最重要的属性和最重要的方法,两者中都有一个叫Transformation的类,可见此类也是很重要的,到Tranfrormation类中可以看到中最重要的属性就是alphat和Matrix, alpha是真正存放动画的透明度信息的,而Matrix则是存放(平移,旋转,绽放)信息的。由此可见这两个才是真正存放一帧动画的的所有信息的载体。

最重要的方法是getMatrix().得到当前帧动画中的存在矩阵中的所有动画信息。

3.由第二点可知,除了透明度信息外,动画的帧信息又是存放在Matrix类中的,所以我们也要看懂Matrix是如何工作的。到了Matrix类中,我们可以看到,此类中提供了一系列的setXXX,preXXX,postXXX方法,即三个系列的对Rotate,Scale,Translate的设置。查阅了网上一些文章,大概明白了三个方法的区别。preXXX方法是对原始矩阵进行右乘,即M*A(以后的M代表原始矩阵),postXXX代表对原始矩阵进行左乘,即 B*M, setXXX代表对原始矩阵数据先清空,再进行右乘。左乘与右乘的区别就是,矩阵进行乘积时会先进行右乘,右乘都执行完后再执行左乘,对应到动画的效果中就是,先叠加右乘矩阵的效果数据,再叠加左乘矩阵的效果数据。可知:左乘与右乘后的效果是完全不同的。具体的矩阵运算说见此文,说的非常好。android Matrix理论与应用。矩阵的都由android系统帮我们处理,程序员要做的只是将偏移量传入到对应的方法中即可。

4.android系统为我们提供的动画都是最基本的,二维的,所以所有的3D动画都要我们自己来实现,而android为我们提供了graphic.camera包下的Camera类,这个类就是实现3D效果的类,我对这个类的理解就是:android系统为我们的程序提供了一双眼睛。就是这个Camera,我们的人眼是可以从XYZ三个轴去观察,那这个Camera也是可以的,通过对Camera类在不同轴上的移动,也是可以达到动画效果的,从Camera类的代码中可以看出它的几个方法:public native void translate(float x, float y, float z)和public native void rotate(float x, float y, float z) ,public void getMatrix(Matrix matrix).这三个方法,第一个是在xyz三个轴上对Camera进行移动,Camera向左移,则可以达到向右的平移动画效果。其它平移效果同理。第二个方法则是在XYZ轴上的旋转,通过在这三个轴上进行旋转,可以达到立体的动画效果,第三个方法则是将在Camera上的操作全部叠加到Matric对象中。

将以上四个类的作用全部搞懂后,我们就基本明白了android的动画原理, 通过继承基类:Aniomation并重写applyTransformation,并将一些效果利用Matrix,Camera实现,就是动画。

下面,我们通过Camera来实现一般的旋转动画和3D旋转动画,以及利用Camear实现我们常用的缩放动画。

1)利用Camera实现平移动画..

?
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
50
51
52
package com.example.animationdemo;
 
import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;
 
public class CameraTranslateAnimation extends Animation {
 
     private float mFromXValue = 0 .0f;
     private float mToXValue = 0 .0f;
 
     private float mFromYValue = 0 .0f;
     private float mToYValue = 0 .0f;
 
     private float centerX, centerY;
     private Camera camera;
 
     public CameraTranslateAnimation( float fromXValue, float toXValue,
             float fromYValue, float toYValue, float centerX, float centerY) {
         this .mFromXValue = fromXValue;
         this .mToXValue = toXValue;
         this .mFromYValue = fromYValue;
         this .mToYValue = toYValue;
         this .centerX = centerX;
         this .centerY = centerY;
 
     }
 
     @Override
     public void initialize( int width, int height, int parentWidth,
             int parentHeight) {
         // TODO Auto-generated method stub
         super .initialize(width, height, parentWidth, parentHeight);
         camera = new Camera();
     }
 
     @Override
     protected void applyTransformation( float interpolatedTime, Transformation t) {
 
         float dx = (mFromXValue + (mToXValue - mFromXValue) * interpolatedTime);
         float dy = (mFromYValue + (mToYValue - mFromYValue) * interpolatedTime);
 
         Matrix m = t.getMatrix();
         camera.save();
         camera.translate(dx, dy, 0 ); // 给要移动的坐标传值
         camera.getMatrix(m);
         camera.restore();
         m.preTranslate(-centerX, -centerY);
         m.postTranslate(centerX, centerY); // 回到中心点
     }
}
2)利用Camera实现旋转动画.

 

 

?
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.example.animationdemo;
 
import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;
 
public class CameraRotateAnimation 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 CameraRotateAnimation( 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) {
         // TODO Auto-generated method stub
         super .initialize(width, height, parentWidth, parentHeight);
         mCamera = new Camera();
     }
 
     /**
      * 注意 applyTransformation函数也是一个不停循环调用的过程.和Adapter中的getView类似
      * 绘制动画时,总是根据Transformation中的位置,缩放,平移等信息去绘制每一帧, 从而达到动画的效果
      */
     @Override
     protected void applyTransformation( float interpolatedTime, Transformation t) {
         // TODO Auto-generated method stub
         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(); // 得到Transformation中的所有动画信息矩阵(都存放在矩阵中)
         camera.save();
         if (mReverse) {
             camera.translate( 0 .0f, 0 .0f, -mDepthZ * interpolatedTime); // 在不同轴上的平移效果,通过移动Camear实现
         } else {
             camera.translate( 0 .0f, 0 .0f, mDepthZ * ( 1 .0f - interpolatedTime));
         }
         camera.rotateY(degrees); // 将角度变化用在Y轴上, 用在Z轴上的旋转是,则是普通的旋转
         camera.getMatrix(matrix); // 必须将此矩阵信息叠加到动画的矩阵中,否则在Camera上的设置都不起作用
         camera.restore();
         matrix.preTranslate(-centerX, -centerY); //回到中心点
         matrix.postTranslate(centerX, centerY);
     }
 
}
总结:通过对 Camera的学习,我们可以很容易的实现一些特殊效果的动画.只有真正掌握了android系统的动画原理,才能真正掌握动画的实现.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值