最近在做一個左面launcher,裏面獲取安裝圖片,有的大 有的小,這樣子就會覺得現實很不好看。所以我決定給他加一個遮罩來實現看起來是一樣的大小
效果不是很好看,後期背景換成一個就會好看很多了。
首先我們來說說思路:
1.首先我們要自定義一個類,繼承Imageview
2.在ondraw() 調用canvas-->// 創建一個和原始圖片一樣大小的矩形
canvas.drawBitmap(cutBm, 0, 0, paint);
3再在中間挖一個空洞,自然是要和我們要放進去的圖片一樣大的空洞,並放入我們要顯示的圖片
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
if (bitmap == null) {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.computer);
}
//控件要顯示的圖
// bitmap = BitmapUtil.toSizeBitmap(bitmap, w, h);
canvas.drawBitmap(cutBm, 0, 0, paint);
int saveFlags = Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG
| Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG
| Canvas.CLIP_TO_LAYER_SAVE_FLAG;
canvas.saveLayer(0, 0, w, h, null, saveFlags);
int left = cutWidth / 2 - bitmap.getWidth() / 2;
int top = cutHeight / 2 - bitmap.getHeight() / 2;
// 創建一個和原始圖片一樣大小的矩形
canvas.drawBitmap(bitmap,left,top, paint);
// 取兩層繪製交集。顯示上層。
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, left, top, paint);
paint.setXfermode(null);
canvas.restore();
這樣就是我們要的效果了,其實這個主要的技術還是涉及到了PorterDuffXfermode類的使用方法,PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
上面就是PorterDuffXfermode類的創建,那麼裏面的參數PorterDuff.Mode.SRC_IN其實有很多中情況,好像有達到16中情況,下面介紹一下常用的:
PorterDuff.Mode.SRC_IN:取兩層繪製交集。顯示上層。就是如果上面兩張圖片相疊,那麼取這兩張圖片的交集而且顯示的是上層那種圖片
PorterDuff.Mode.DST_IN: 取兩層繪製交集。顯示下層。
通過調用這個PorterDuff.Mode.SRC_IN,來控制空出來的圖片正好和我們需要的圖片大小一樣,達到我們要的遮罩效果
自然我是有寫好的demo給大家的。但是在項目中不好拷貝,就直接將我的自定義的view貼出來給大家看,有問題的可以私信我。
/**
* 圖片加遮罩view
*/
public class CanSetImageView extends ImageView {
private Context context;
public CanSetImageView(Context context) {
this(context, null);
}
public CanSetImageView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public CanSetImageView(Context context, AttributeSet attrs, int defStyle) {
this(context, attrs);
}
private Bitmap decodeBitmap(int resId) {
return BitmapFactory.decodeResource(context.getResources(), resId);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
int w = this.getWidth();
int h = this.getHeight();
Paint paint = new Paint();
//應用資源文件的圖片
Bitmap cutBm = decodeBitmap(R.mipmap.round);
cutBm = BitmapUtil.toSizeBitmap(cutBm, w, h);
int cutWidth = cutBm.getWidth();
int cutHeight = cutBm.getHeight();
Drawable drawable = getDrawable();
if (null != drawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
if (bitmap == null) {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.computer);
}
//控件要顯示的圖
// bitmap = BitmapUtil.toSizeBitmap(bitmap, w, h);
canvas.drawBitmap(cutBm, 0, 0, paint);
int saveFlags = Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG
| Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG
| Canvas.CLIP_TO_LAYER_SAVE_FLAG;
canvas.saveLayer(0, 0, w, h, null, saveFlags);
int left = cutWidth / 2 - bitmap.getWidth() / 2;
int top = cutHeight / 2 - bitmap.getHeight() / 2;
// 創建一個和原始圖片一樣大小的矩形
canvas.drawBitmap(bitmap,left,top, paint);
// 取兩層繪製交集。顯示上層。
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, left, top, paint);
paint.setXfermode(null);
canvas.restore();
if(cutBm.isRecycled()){
cutBm.recycle();
}
if(bitmap.isRecycled()){
bitmap.recycle();
}
}
}
}
參考博文:http://jingpin.jikexueyuan.com/article/55827.html