1. 程式人生 > >Android高階圖片滾動控制元件,編寫3D版的圖片輪播器 一屏顯示多個圖片

Android高階圖片滾動控制元件,編寫3D版的圖片輪播器 一屏顯示多個圖片

大家好,好久不見了,最近由於工作特別繁忙,已經有一個多月的時間沒寫部落格了,我也是深感慚愧。那麼今天的這篇既然是闊別了一個多月的文章,當然要帶來更加給力點的內容了,那麼話不多說,趕快進入到今天的正題吧。

說到圖片輪播器,很多的Android應用中都會帶有這個功能,比如說網易新聞、淘寶等。最新我們公司的一款應用也加入了這個功能,並且在圖片輪播的基礎上還增加了三維立體的效果,但比較遺憾的是,整體效果並不理想,使用者體驗性比較糟糕。因此,我就花了點時間去編寫了一個效果更好的3D圖片輪播器,自我感覺還是比較滿意的,這裡果斷寫一篇部落格來分享給大家。

首先來介紹一下實現原理吧,傳統的圖片輪播器在一個介面上只會顯示一張圖片,要用手指進行左右滑動才能看到其它的圖片。這裡我們將思維發散一下,允許在一個介面上同時顯示三張圖片,再通過Camera的方式對左右的兩張圖進行3D旋轉,這樣就能製作出一種立體的圖片輪播器了,原理示意圖如下所示:



對圖片進行立體操作還是要使用到Camera技術,如果你對這個技術還不太熟悉,可以到網上搜一些相關資料,或者參考我前面的一篇文章:Android中軸旋轉特效實現,製作別樣的圖片瀏覽器 。

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

然後新建一個Image3DView繼承自ImageView,它會繼承ImageView的所有屬性,並且加入3D旋轉的功能,程式碼如下所示:


  1. publicclass Image3DView extends ImageView {  
  2.     /**
     
  3.      * 旋轉角度的基準值 
  4.      */
  5.     privatestaticfinalfloat BASE_DEGREE = 50f;  
  6.     /** 
  7.      * 旋轉深度的基準值 
  8.      */
  9.     privatestaticfinalfloat BASE_DEEP = 150f;  
  10.     private Camera mCamera;  
  11.     private Matrix mMaxtrix;  
  12.     private Bitmap mBitmap;  
  13.     /** 
  14.      * 當前圖片對應的下標 
  15.      */
  16.     private
    int mIndex;  
  17.     /** 
  18.      * 在前圖片在X軸方向滾動的距離 
  19.      */
  20.     privateint mScrollX;  
  21.     /** 
  22.      * Image3DSwitchView控制元件的寬度 
  23.      */
  24.     privateint mLayoutWidth;  
  25.     /** 
  26.      * 當前圖片的寬度 
  27.      */
  28.     privateint mWidth;  
  29.     /** 
  30.      * 當前旋轉的角度 
  31.      */
  32.     privatefloat mRotateDegree;  
  33.     /** 
  34.      * 旋轉的中心點 
  35.      */
  36.     privatefloat mDx;  
  37.     /** 
  38.      * 旋轉的深度 
  39.      */
  40.     privatefloat mDeep;  
  41.     public Image3DView(Context context, AttributeSet attrs) {  
  42.         super(context, attrs);  
  43.         mCamera = new Camera();  
  44.         mMaxtrix = new Matrix();  
  45.     }  
  46.     /** 
  47.      * 初始化Image3DView所需要的資訊,包括圖片寬度,擷取背景圖等。 
  48.      */
  49.     publicvoid initImageViewBitmap() {  
  50.         if (mBitmap == null) {  
  51.             setDrawingCacheEnabled(true);  
  52.             buildDrawingCache();  
  53.             mBitmap = getDrawingCache();  
  54.         }  
  55.         mLayoutWidth = Image3DSwitchView.mWidth;  
  56.         mWidth = getWidth() + Image3DSwitchView.IMAGE_PADDING * 2;  
  57.     }  
  58.     /** 
  59.      * 設定旋轉角度。 
  60.      *  
  61.      * @param index 
  62.      *            當前圖片的下標 
  63.      * @param scrollX 
  64.      *            當前圖片在X軸方向滾動的距離 
  65.      */
  66.     publicvoid setRotateData(int index, int scrollX) {  
  67.         mIndex = index;  
  68.         mScrollX = scrollX;  
  69.     }  
  70.     /** 
  71.      * 回收當前的Bitmap物件,以釋放記憶體。 
  72.      */
  73.     publicvoid recycleBitmap() {  
  74.         if (mBitmap != null && !mBitmap.isRecycled()) {  
  75.             mBitmap.recycle();  
  76.         }  
  77.     }  
  78.     @Override
  79.     publicvoid setImageResource(int resId) {  
  80.         super.setImageResource(resId);  
  81.         mBitmap = null;  
  82.         initImageViewBitmap();  
  83.     }  
  84.     @Override
  85.     publicvoid setImageBitmap(Bitmap bm) {  
  86.         super.setImageBitmap(bm);  
  87.         mBitmap = null;  
  88.         initImageViewBitmap();  
  89.     }  
  90.     @Override
  91.     publicvoid setImageDrawable(Drawable drawable) {  
  92.         super.setImageDrawable(drawable);  
  93.         mBitmap = null;  
  94.         initImageViewBitmap();  
  95.     }  
  96.     @Override
  97.     publicvoid setImageURI(Uri uri) {  
  98.         super.setImageURI(uri);  
  99.         mBitmap = null;  
  100.         initImageViewBitmap();  
  101.     }  
  102.     @Override
  103.     protectedvoid onDraw(Canvas canvas) {  
  104.         if (mBitmap == null) {  
  105.             // 如果Bitmap物件還不存在,先使用父類的onDraw方法進行繪製
  106.             super.onDraw(canvas);  
  107.         } else {  
  108.             if (isImage