效果
核心思路:Xfermode的使用,两个图层一个为实际图片。一个为需要显示部分透明的图。
开始想可能得自定义view,感觉蛮复杂的。最后发现可以简单点。用UI切个图。简单继承下ImageView就行了。
算了不说了贴代码了
/**Created by lps on 2017/2/13. */
public class IrregularImageView extends ImageView {
private Context mContext;
private Paint mPaint;
Bitmap dst;
private int mWidth;
private int mHeight;
public IrregularImageView(Context context) {
this(context, null);
}
public IrregularImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public IrregularImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
if (getDrawable() == null || dst == null) return;//如果没有设置图片就不往下绘制了
mWidth = getWidth();
mHeight = getHeight();
int sc = canvas.saveLayer(0, 0, mWidth, mHeight, null, 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);
// 先画一个图片
Bitmap mask = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.irregular);
mask = calculateMask(mask, mWidth, mHeight);
canvas.drawBitmap(dst, 0, 0, mPaint);
// 设置模式
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
canvas.drawBitmap(mask, 0, 0, mPaint);
// 还原混合模式
mPaint.setXfermode(null);
// 还原画布
canvas.restoreToCount(sc);
}
private Bitmap calculateMask(Bitmap mMask, int mWidth, int mHeight) {
Matrix mMatrix = new Matrix();
float scaleX = mWidth * 1.0f / (mMask.getWidth() * 1.0f);
float scaleY = mHeight * 1.0f / (mMask.getHeight() * 1.0f);
mMatrix.postScale(scaleX, scaleY);
Bitmap mBitmap = Bitmap.createBitmap(mMask, 0, 0, mMask.getWidth(), mMask.getHeight(), mMatrix, true);
return mBitmap;
}
/** * 以下四个函数都是
* 复写ImageView的setImageXxx()方法
* 注意这个函数先于构造函数调用之前调用
* @param bm*/
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
dst = bm;
setup();
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
dst = getBitmapFromDrawable(drawable);
System.out.println("setImageDrawable -- setup");
setup();
}
@Override
public void setImageResource(@DrawableRes int resId) {
super.setImageResource(resId);
dst = getBitmapFromDrawable(getDrawable());
setup();
}
@Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
dst = getBitmapFromDrawable(getDrawable());
setup();
}
/**
* Drawable转Bitmap
*
* @param drawable 因为用Glide做的图片加载。有一些Glide影响的因素,这个方法可能还有待完善
* @return
*/
private Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable == null) {
return null;
}
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
if (drawable instanceof TransitionDrawable) {
GlideBitmapDrawable mDrawableByLayerId = (GlideBitmapDrawable) ((TransitionDrawable) (drawable)).findDrawableByLayerId(((TransitionDrawable) drawable).getId(1));
return mDrawableByLayerId.getBitmap();
}
if (drawable instanceof GlideBitmapDrawable) {
return ((GlideBitmapDrawable) drawable).getBitmap();
}
return null;
}
private void setup() {
if (dst == null) return;
invalidate();
}}
最后附上UI妹子给的图。