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

来源:互联网 发布:网站整站下载器 mac 编辑:程序博客网 时间:2024/05/17 08:14

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

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

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

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

   2.由上面的Animation类,可以知道最重要的属性和最重要的方法,两者中都有一个叫Transformation的类,可见此类也是很重要的,到Tranfrormation类中可以看到中最重要的属性就是alphatMatrix, 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实现平移动画..

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;}@Overridepublic void initialize(int width, int height, int parentWidth,int parentHeight) {// TODO Auto-generated method stubsuper.initialize(width, height, parentWidth, parentHeight);camera = new Camera();}@Overrideprotected 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实现旋转动画.

  

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;}@Overridepublic void initialize(int width, int height, int parentWidth,int parentHeight) {// TODO Auto-generated method stubsuper.initialize(width, height, parentWidth, parentHeight);mCamera = new Camera();}/** * 注意 applyTransformation函数也是一个不停循环调用的过程.和Adapter中的getView类似 * 绘制动画时,总是根据Transformation中的位置,缩放,平移等信息去绘制每一帧, 从而达到动画的效果 */@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {// TODO Auto-generated method stubfinal 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系统的动画原理,才能真正掌握动画的实现.demo代码上传,有需要的可以下载查看.

  demo源码 

 

2 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 特别害怕和导师交流怎么办 面试工资要少了怎么办 一面工资要低了怎么办 家乐卡到期本金还一半怎么办 新三板公司没有资不抵债没钱怎么办 户户通智能卡坏了怎么办 秦岭云无法回看怎么办 身份证在火车站丢了怎么办 到火车站发现身份证丢了怎么办 广电宽带太慢了怎么办 车有后雷达想装前置雷达怎么办 现代朗动油耗大怎么办 雷达线雕头里有水怎么办 上古卷轴5免疫死亡奴役怎么办 dw手表时针不动了怎么办 雷达陶瓷表壳摔坏了怎么办 雷达表盘摔坏了怎么办 雷达测速60超了怎么办 卡西欧手表电池没电了怎么办 审稿人让引用他的文章怎么办 考二建未从事该行业满两年怎么办 2档换3档离合器怎么办 高铁车票丢了怎么办 事业编制调动原单位不同意怎么办 想去铁路上工作怎么办 房产权50年以后怎么办 在香港手机没电怎么办 学校官网登陆忘记密码怎么办 网上申报学校忘记密码怎么办 专转本想换专业怎么办 发生工伤没有平均公资怎么办? 单招过了不想去怎么办 22岁了还想复读怎么办 父母不让我读大专了怎么办 专升本考试失利怎么办 高考复读一年后失败了怎么办? 医保住院超过30万怎么办 北京医保超过2万怎么办 工伤公司垫付医疗费没法报销怎么办 司法考试照片耳朵露不出来怎么办 新华社毕业证照片用光了怎么办