Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android動畫之從源碼角度分析動畫原理

android動畫之從源碼角度分析動畫原理

編輯:關於Android編程

以前一直不懂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實現平移動畫..

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實現旋轉動畫.

 

 

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系統的動畫原理,才能真正掌握動畫的實現.demo代碼上傳,有需要的可以下載查看.

 

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved