編輯: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 */ }
 
先看效果圖,有圖有效果了才有動力(右邊是關閉wifi/3g之後的Title樣子)首先了解一下網絡狀態的判斷方法,網絡狀態是一個SystemService,可以通過cont
前言Android Build 系統是 Android 源碼的一部分。關於如何獲取 Android 源碼,請參照 Android Source 官方網站:http://s
深度OS是shendu.com 旗下的一款基於谷歌安卓代碼二次開發的安卓第三方ROM,基於底層的優化和開發,使得即使在較低配置的千元智能機,也能夠流暢的運行最新版本的安卓
變態問題常有,今年特別多,,, - - # 今天遇到的這個非處理不可,不然沒法在HTC One S使用SearchView,其軟鍵盤不支持action設置。問題設備:HT