Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android系統教程 >> Android開發教程 >> Android的改進版CoverFlow效果控件

Android的改進版CoverFlow效果控件

編輯:Android開發教程

最近研究了一下如何在Android上實現CoverFlow效果的控件,其實早在2010年,就有Neil Davies開發並開源出了這個控件,Neil大神的這篇博客地址http://www.inter-fuser.com/2010/02/android-coverflow-widget-v2.html。首先是閱讀源碼,弄明白核心思路後,自己重新寫了一遍這個控件,並加入了詳盡的注釋以便日後查閱;而後在使用過程中,發現了有兩點可以改進:(1)初始圖片位於中間,左邊空了一半空間,比較難看,可以改為重復滾動地展示、(2)由於圖片一開始就需要加載出來,所以對內存開銷較大,很容易OOM,需要對圖片的內存空間進行壓縮。

這個自定義控件包括4個部分,用於創建及提供圖片對象的ImageAdapter,計算圖片旋轉角度等的自定義控件GalleryFlow,壓縮采樣率解析Bitmap的工具類BitmapScaleDownUtil,以及承載自定義控件的Gallery3DActivity。

首先是ImageAdapter,代碼如下:

package pym.test.gallery3d.widget;
    
import pym.test.gallery3d.util.BitmapScaleDownUtil;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
    
/**
 * @author pengyiming
 * @date 2013-9-30
 * @function GalleryFlow適配器
 */
public class ImageAdapter extends BaseAdapter
{
    /* 數據段begin */
    private final String TAG = "ImageAdapter";
    private Context mContext;
        
    //圖片數組
    private int[] mImageIds ;
    //圖片控件數組
    private ImageView[] mImages;
    //圖片控件LayoutParams
    private GalleryFlow.LayoutParams mImagesLayoutParams;
    /* 數據段end */
    
    /* 函數段begin */
    public ImageAdapter(Context context, int[] imageIds)
    {
        mContext = context;
        mImageIds = imageIds;
        mImages = new ImageView[mImageIds.length];
        mImagesLayoutParams = new GalleryFlow.LayoutParams(Gallery.LayoutParams.WRAP_CONTENT, Gallery.LayoutParams.WRAP_CONTENT);
    }
        
    /**
     * @function 根據指定寬高創建待繪制的Bitmap,並繪制到ImageView控件上
     * @param imageWidth
     * @param imageHeight
     * @return void
     */
    public void createImages(int imageWidth, int imageHeight)
    {
        // 原圖與倒影的間距5px
        final int gapHeight = 5;
            
        int index = 0;
        for (int imageId : mImageIds)
        {
            /* step1 采樣方式解析原圖並生成倒影 */
            // 解析原圖,生成原圖Bitmap對象
//            Bitmap originalImage = BitmapFactory.decodeResource(mContext.getResources(), imageId);
            Bitmap originalImage = BitmapScaleDownUtil.decodeSampledBitmapFromResource(mContext.getResources(), imageId, imageWidth, imageHeight);
            int width = originalImage.getWidth();
            int height = originalImage.getHeight();
                
            // Y軸方向反向,實質就是X軸翻轉
            Matrix matrix = new Matrix();
            matrix.setScale(1, -1);
            // 且僅取原圖下半部分創建倒影Bitmap對象
            Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height / 2, width, height / 2, matrix, false);
                
            /* step2 繪制 */
            // 創建一個可包含原圖+間距+倒影的新圖Bitmap對象
            Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + gapHeight + height / 2), Config.ARGB_8888);
            // 在新圖Bitmap對象之上創建畫布
            Canvas canvas = new Canvas(bitmapWithReflection);
            // 抗鋸齒效果
            canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG));
            // 繪制原圖
            canvas.drawBitmap(originalImage, 0, 0, null);
            // 繪制間距
            Paint gapPaint = new Paint();
            gapPaint.setColor(0xFFCCCCCC);
            canvas.drawRect(0, height, width, height + gapHeight, gapPaint);
            // 繪制倒影
            canvas.drawBitmap(reflectionImage, 0, height + gapHeight, null);
                
            /* step3 渲染 */
            // 創建一個線性漸變的渲染器用於渲染倒影
            Paint paint = new Paint();
            LinearGradient shader = new LinearGradient(0, height, 0, (height + gapHeight + height / 2), 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
            // 設置畫筆渲染器
            paint.setShader(shader);
            // 設置圖片混合模式
            paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
            // 渲染倒影+間距
            canvas.drawRect(0, height, width, (height + gapHeight + height / 2), paint);
                
            /* step4 在ImageView控件上繪制 */
            ImageView imageView = new ImageView(mContext);
            imageView.setImageBitmap(bitmapWithReflection);
            imageView.setLayoutParams(mImagesLayoutParams);
            // 打log
            imageView.setTag(index);
                
            /* step5 釋放heap */
            originalImage.recycle();
            reflectionImage.recycle();
//          bitmapWithReflection.recycle();
                
            mImages[index++] = imageView;
        }
    }
    
    @Override
    public int getCount()
    {
        return Integer.MAX_VALUE;
    }
        
    @Override
    public Object getItem(int position)
    {
        return mImages[position];
    }
        
    @Override
    public long getItemId(int position)
    {
        return position;
    }
        
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        return mImages[position % mImages.length];
    }
    /* 函數段end */
}

 

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