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