Android 使用Gallery實現3D相簿(附效果圖+Demo源碼)

來源:互聯網
上載者:User

今天主要是說說如何?Gallery的3D顯示切換,Demo的代碼很多是基於網上一些現成效果,感謝這些分享成果的開發人員 

今天因為要做一個設定開機畫面的功能,主要是讓使用者可以設定自己的開機畫面,應用程式層需要做讓使用者選擇開機畫面圖片的功能。所以需要做一個簡單的圖片瀏覽選擇程式。最後選用Gallery作為基本控制項。加入了一些炫一點的元素,做成3D滑動效果。下面是Demo例子:

 

這個效果網上已經很多人做出來了,只是這次需要用到,所以自己也實踐了一下(這裡例子我也是根據網上一些資料編寫)。特意找了幾張美女 圖片給大家養養眼,O(∩_∩)O哈!下面針對一些關鍵代碼進行簡要說明,需要做這方面東西的朋友可以看看。這篇文章是實用性文章,理論分析不多。

1、重載Gallery類
因 為需要加入倒影和3D切換的效果,因此我們需要重載Gallery類,其中有兩個方法我們需要重寫,一個是onSizeChanged(),另外一個是 getChildStaticTransformation()。下面我們看看onSizeChanged()需要做的事情。

複製代碼 代碼如下:
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
//重寫計算旋轉的中心
        mCoveflowCenter = getCenterOfCoverflow();
        super.onSizeChanged(w, h, oldw, oldh);
    }


上面主要做的事情就是在改變大小的時候,重新計算滑動切換時需要旋轉變化的中心。下面計算圖片位置時,會重新計算。

複製代碼 代碼如下:
protected boolean getChildStaticTransformation(View child, Transformation trans)
    {
//映像的中心點和寬度
        final int childCenter = getCenterOfView(child);
        final int childWidth = child.getWidth();
        int rotationAngle = 0;

        trans.clear();
        trans.setTransformationType(Transformation.TYPE_BOTH);        // alpha 和 matrix 都變換

        if (childCenter == mCoveflowCenter)
        {   
  // 正中間的childView
            transformImageBitmap((ImageView) child, trans, 0);   
        }
        else
        {       
  // 兩側的childView
            rotationAngle = (int) ( ( (float) (mCoveflowCenter - childCenter) / childWidth ) * mMaxRotationAngle );
            if (Math.abs(rotationAngle) > mMaxRotationAngle)
            {
                rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;
            }
//根據位移角度對圖片進行處理,看上去有3D的效果。
            transformImageBitmap((ImageView) child, trans, rotationAngle);
        }

        return true;
    }


上面就是重載Gallery的時候,需要注意處理的事情,其實主要就是做圖形變化,裡面的圖片斜著顯示就是這裡處理的結果,目的就是讓人看上去有立體感。

2、編寫Adapter適配器
我們使用很多控制項都涉及適配器,就是用來綁定資料來源和目標控制項的一個中介軟體。這裡我們需要重載BaseAdapter作為我們Gallery的適配器。主要是處理源映像,加入倒影,產生新的資料來源圖片。

複製代碼 代碼如下:
public boolean createReflectedForAdapter()
    {
        final int reflectionGap = 4;
        final int Height = 200;
        int index = 0;
        for (Map<String, Object> map : list)
        {
            Integer id = (Integer) map.get("image");
            // 擷取原始圖片
            Bitmap originalImage = BitmapFactory.decodeResource(mContext.getResources(), id);   
            int width = originalImage.getWidth();
            int height = originalImage.getHeight();
            float scale = Height / (float)height;

            Matrix sMatrix = new Matrix();
            sMatrix.postScale(scale, scale);
            Bitmap miniBitmap = Bitmap.createBitmap(originalImage, 0, 0,
                    originalImage.getWidth(), originalImage.getHeight(), sMatrix, true);

            //是否原圖片資料,節省記憶體
            originalImage.recycle();

            int mwidth = miniBitmap.getWidth();
            int mheight = miniBitmap.getHeight();
            Matrix matrix = new Matrix();
            // 圖片矩陣變換(從低部向頂部的倒影)
            matrix.preScale(1, -1);           
            // 截取原圖下半部分
            Bitmap reflectionImage = Bitmap.createBitmap(miniBitmap, 0, mheight/2, mwidth, mheight/2, matrix, false);
            // 建立倒影圖片(高度為原圖3/2)
            Bitmap bitmapWithReflection = Bitmap.createBitmap(mwidth, (mheight + mheight / 2), Config.ARGB_8888);   
            // 繪製倒影圖(原圖 + 間距 + 倒影)
            Canvas canvas = new Canvas(bitmapWithReflection);   
            // 繪製原圖
            canvas.drawBitmap(miniBitmap, 0, 0, null);       
            Paint paint = new Paint();
            // 繪製原圖與倒影的間距
            canvas.drawRect(0, mheight, mwidth, mheight + reflectionGap, paint);
            // 繪製倒影圖
            canvas.drawBitmap(reflectionImage, 0, mheight + reflectionGap, null);   

            paint = new Paint();
            // 線性漸層效果
            LinearGradient shader = new LinearGradient(0, miniBitmap.getHeight(), 0, bitmapWithReflection.getHeight()
                    + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
            paint.setShader(shader);   
            // 倒影遮罩效果
            paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));       
            // 繪製倒影的陰影製作效果
            canvas.drawRect(0, mheight, mwidth, bitmapWithReflection.getHeight() + reflectionGap, paint);       
            ImageView imageView = new ImageView(mContext);
  // 設定倒影圖片
            imageView.setImageBitmap(bitmapWithReflection);       
            imageView.setLayoutParams(new GalleryView.LayoutParams((int)(width * scale),
                    (int)(mheight * 3 / 2.0 + reflectionGap)));
            imageView.setScaleType(ScaleType.MATRIX);
            mImages[index++] = imageView;
        }
        return true;
    }

上面其實就是一個圖片處理過程,主要做的事情就是產生倒影,裡面底下是有倒影的。就是利用上面演算法產生。我們在適配器添加圖片的時候,會把適 配器原生圖片進行處理,加入倒影的效果。這個我們在圖片初始化的時候就可以調用處理,具體代碼可以查看Demo裡面的代碼關係。

具體圖片滑動的過程,Gallery會幫我們處理好,我們要做的事情其實就是提供添加了特效的圖片資料來源,以及處理3D顯示的變化效果,最後都會提供View作為顯示映像給Gallery用來顯示。

今天主要是說說如何?Gallery的3D顯示切換,Demo的代碼很多是基於網上一些現成效果,感謝這些分享成果的開發人員。下面是Demo的下載,不清楚的可以把Demo下載下來,運行看看效果然後分析一下代碼。代碼不多,也不是很複雜。

 

Gallery3D例子代碼:點擊下載

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.