本文來自:http://blog.csdn.net/guolin_blog/article/detals/10471245
在上一篇文章中,我們學習了Camera的基本用法,並借助它們編寫了一個例子,實現了類似於API Demos裡的圖片中軸旋轉功能。不過那個例子的核心代碼是來自於API Demos中帶有的Rotate3dAnimation這個類,是它幫助我們完成了所有的三維旋轉操作,所有Matrix和Camera相關的代碼也是封裝在這個類中。
這樣說來的話,大家心裡會不會癢癢的呢?雖然學習了Camera的用法,但卻沒有按照自己的理解來實現一套非常炫酷的3D效果。不要著急,今天我就帶著大家一起來實現一種3D推拉門式的滑動菜單,而且完全不會借助任何API Demos裡面的代碼。
當然如果你還不是很了解Camera的使用方式,可以先去閱讀我的上一篇文章 Android中軸旋轉特效實現,制作別樣的圖片浏覽器 http://www.linuxidc.com/Linux/2013-09/90443.htm。
關於滑動菜單的文章我也已經寫過好幾篇了,相信看過的朋友對滑動菜單的實現方式應該都已經比較熟悉了,那麼本篇文章的重點就在於,如何在傳統滑動菜單的基礎上加入推拉門式的立體效果。還不了解滑動菜單如何實現的朋友,可以去翻一翻我之前的文章。
本文示例源碼下載:
免費下載地址在 http://linux.linuxidc.com/
用戶名與密碼都是www.linuxidc.com
具體下載目錄在 /2013年資料/10月/4日/Android 3D滑動菜單完全解析,實現推拉門式的立體特效
下載方法見 http://www.linuxidc.com/Linux/2013-07/87684.htm
首先來講一下這次的實現原理吧,其實傳統的滑動菜單功能就是把菜單部分放在了下面,主布局放在了上面,然後根據手指滑動的距離來偏移主布局,讓菜單部分得以顯示出來就行了。不過我們這次既然要做推拉門式的立體效果,就需要將傳統的思維稍微轉變一下,可以先讓菜單部分隱藏掉,但卻復制一個菜單的鏡像並生成一張圖片,然後在手指滑動的時候對這張圖片進行三維操作,讓它產生推拉門式的效果,等滑動操作結束的時候,才讓真正的菜單顯示出來,然後將這個圖片隱藏。原理示意圖如下所示:
那麼下面我們就開始動手實現吧,首先新建一個Android項目,起名叫做ThreeDSlidingLayoutDemo。
然後新建一個Image3dView類繼承自View,用於生成鏡像圖片,以及完成三維操作,代碼如下所示:
public class Image3dView extends View {
/**
* 源視圖,用於生成圖片對象。
*/
private View sourceView;
/**
* 根據傳入的源視圖生成的圖片對象。
*/
private Bitmap sourceBitmap;
/**
* 源視圖的寬度。
*/
private float sourceWidth;
/**
* Matrix對象,用於對圖片進行矩陣操作。
*/
private Matrix matrix = new Matrix();
/**
* Camera對象,用於對圖片進行三維操作。
*/
private Camera camera = new Camera();
/**
* Image3dView的構造函數
*
* @param context
* @param attrs
*/
public Image3dView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 提供外部接口,允許向Image3dView傳入源視圖。
*
* @param view
* 傳入的源視圖
*/
public void setSourceView(View view) {
sourceView = view;
sourceWidth = sourceView.getWidth();
}
/**
* 清除掉緩存的圖片對象。
*/
public void clearSourceBitmap() {
if (sourceBitmap != null) {
sourceBitmap = null;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (sourceBitmap == null) {
getSourceBitmap();
}
// 計算圖片需要旋轉的角度
float degree = 90 - (90 / sourceWidth) * getWidth();
camera.save();
camera.rotateY(degree);
camera.getMatrix(matrix);
camera.restore();
// 將旋轉的中心點移動到屏幕左邊緣的中間位置
matrix.preTranslate(0, -getHeight() / 2);
matrix.postTranslate(0, getHeight() / 2);
canvas.drawBitmap(sourceBitmap, matrix, null);
}
/**
* 獲取源視圖對應的圖片對象。
*/
private void getSourceBitmap() {
if (sourceView != null) {
sourceView.setDrawingCacheEnabled(true);
sourceView.layout(0, 0, sourceView.getWidth(), sourceView.getHeight());
sourceView.buildDrawingCache();
sourceBitmap = sourceView.getDrawingCache();
}
}
}
接下來請看第2頁精彩內容: http://www.linuxidc.com/Linux/2013-10/90958p2.htm