1. 程式人生 > >Android 3D滑動選單完全解析,實現推拉門式的立體特效

Android 3D滑動選單完全解析,實現推拉門式的立體特效

轉載地址:http://blog.csdn.net/guolin_blog/article/details/10471245

下面還是回到正題,首先來講一下這次的實現原理吧,其實傳統的滑動選單功能就是把選單部分放在了下面,主佈局放在了上面,然後根據手指滑動的距離來偏移主佈局,讓選單部分得以顯示出來就行了。不過我們這次既然要做推拉門式的立體效果,就需要將傳統的思維稍微轉變一下,可以先讓選單部分隱藏掉,但卻複製一個選單的映象並生成一張圖片,然後在手指滑動的時候對這張圖片進行三維操作,讓它產生推拉門式的效果,等滑動操作結束的時候,才讓真正的選單顯示出來,然後將這個圖片隱藏。原理示意圖如下所示:

                                      


那麼下面我們就開始動手實現吧,首先新建一個Android專案,起名叫做ThreeDSlidingLayoutDemo。

然後新建一個Image3dView類繼承自View,用於生成映象圖片,以及完成三維操作,程式碼如下所示:

  1. publicclass Image3dView extends View {  
  2.     /** 
  3.      * 源檢視,用於生成圖片物件。 
  4.      */
  5.     private View sourceView;  
  6.     /** 
  7.      * 根據傳入的源檢視生成的圖片物件。 
  8.      */
  9.     private Bitmap sourceBitmap;  
  10.     /** 
  11.      * 源檢視的寬度。 
  12.      */
  13.     privatefloat sourceWidth;  
  14.     /** 
  15.      * Matrix物件,用於對圖片進行矩陣操作。 
  16.      */
  17.     private Matrix matrix = new Matrix();  
  18.     /** 
  19.      * Camera物件,用於對圖片進行三維操作。 
  20.      */
  21.     private Camera camera = new Camera();  
  22.     /** 
  23.      * Image3dView的建構函式 
  24.      *  
  25.      * @param context
     
  26.      * @param attrs 
  27.      */
  28.     public Image3dView(Context context, AttributeSet attrs) {  
  29.         super(context, attrs);  
  30.     }  
  31.     /** 
  32.      * 提供外部介面,允許向Image3dView傳入源檢視。 
  33.      *  
  34.      * @param view 
  35.      *            傳入的源檢視 
  36.      */
  37.     publicvoid setSourceView(View view) {  
  38.         sourceView = view;  
  39.         sourceWidth = sourceView.getWidth();  
  40.     }  
  41.     /** 
  42.      * 清除掉快取的圖片物件。 
  43.      */
  44.     publicvoid clearSourceBitmap() {  
  45.         if (sourceBitmap != null) {  
  46.             sourceBitmap = null;  
  47.         }  
  48.     }  
  49.     @Override
  50.     protectedvoid onDraw(Canvas canvas) {  
  51.         super.onDraw(canvas);  
  52.         if (sourceBitmap == null) {  
  53.             getSourceBitmap();  
  54.         }  
  55.         // 計算圖片需要旋轉的角度
  56.         float degree = 90 - (90 / sourceWidth) * getWidth();  
  57.         camera.save();  
  58.         camera.rotateY(degree);  
  59.         camera.getMatrix(matrix);  
  60.         camera.restore();  
  61.         // 將旋轉的中心點移動到螢幕左邊緣的中間位置
  62.         matrix.preTranslate(0, -getHeight() / 2);  
  63.         matrix.postTranslate(0, getHeight() / 2);  
  64.         canvas.drawBitmap(sourceBitmap, matrix, null);  
  65.     }  
  66.     /** 
  67.      * 獲取源檢視對應的圖片物件。 
  68.      */
  69.     privatevoid getSourceBitmap() {  
  70.         if (sourceView != null) {  
  71.             sourceView.setDrawingCacheEnabled(true);  
  72.             sourceView.layout(00, sourceView.getWidth(), sourceView.getHeight());  
  73.             sourceView.buildDrawingCache();  
  74.             sourceBitmap = sourceView.getDrawingCache();  
  75.         }  
  76.     }  
  77. }  
可以看到,Image3dView中提供了一個setSourceView()方法,用於傳遞源檢視進來,我們稍後複製映象就是對它進行復制。然後在onDraw()方法裡對sourceBitmap進行判斷,如果為空,則去呼叫getSourceBitmap()方法來生成一張映象圖片,getSourceBitmap()方法的細節大家自己去看。在獲得了映象圖片之後,接下來就是要計算圖片的旋轉角度了,這裡根據Image3dView當前的寬度和源檢視的總寬度進行對比,按比例算出旋轉的角度。然後呼叫Camera的rotateY()方法,讓圖片團練Y軸進行旋轉,並將旋轉的中心點移動到螢幕左邊緣的中間位置,這幾行程式碼我們在上篇文章中已經見過了,算是挺熟悉了吧!最後呼叫Canvas的drawBitmap()方法把圖片繪製出來。

完成了Image3dView之後,接著我們要開始編寫滑動選單部分的程式碼,其實這次的程式碼和之前的滑動選單程式碼大同小異,看過我前面文章的朋友,這次理解起來一定會輕而易舉。新建ThreeDSlidingLayout類,程式碼如下所示:

  1. publicclass ThreeDSlidingLayout extends RelativeLayout implements OnTouchListener {  
  2.     /** 
  3.      * 滾動顯示和隱藏左側佈局時,手指滑動需要達到的速度。 
  4.      */
  5.     publicstaticfinalint SNAP_VELOCITY = 200;  
  6.     /** 
  7.      * 滑動狀態的一種,表示未進行任何滑動。 
  8.      */
  9.     publicstaticfinalint DO_NOTHING = 0;  
  10.     /** 
  11.      * 滑動狀態的一種,表示正在滑出左側選單。 
  12.      */
  13.     publicstaticfinalint SHOW_MENU = 1;  
  14.     /** 
  15.      * 滑動狀態的一種,表示正在隱藏左側選單。 
  16.      */
  17.     publicstaticfinalint