本篇:自定义圆形View并显示圆形的头像
目录:
1. 预备:阅读本篇文章,需具备View的绘制基本知识。
2. 讲解:PorterDuff.Mode https://developer.android.com/reference/android/graphics/PorterDuff.Mode
3. 实战:使用PorterDuff.Mode实现圆形头像。
核心代码:
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
PorterDuff.Mode
1. SRC
PorterDuff.Mode.SRC
PorterDuff.Mode.SRC_OVER
PorterDuff.Mode.SRC_IN
PorterDuff.Mode.SRC_OUT
PorterDuff.Mode.SRC_ATOP
2. Destination
PorterDuff.Mode.DST
PorterDuff.Mode.DST_OVER
PorterDuff.Mode.DST_IN
PorterDuff.Mode.DST_OUT
PorterDuff.Mode.DST_ATOP
3. Clear
######PorterDuff.Mode.CLEAR
4. Exclusive or
PorterDuff.Mode.XOR
PorterDuff.Mode,实现圆形头像 (支持Padding、wrap_content属性)
1. 核心代码
public class AirXfermodeCircleView extends ImageView {
private static final String TAG = "AirXfermodeCircleView";
private static final int MIN_SIZE_DEFAULT = 100;
private Paint mDrawablePaint;
public AirXfermodeCircleView(Context context) {
this(context, null);
}
public AirXfermodeCircleView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public AirXfermodeCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public AirXfermodeCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initializePaints();
}
private void initializePaints() {
mDrawablePaint = new Paint();
mDrawablePaint.setAntiAlias(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
switch (widthMode) {
case MeasureSpec.AT_MOST:
widthSize = dpToPx(MIN_SIZE_DEFAULT);
break;
}
switch (heightMode) {
case MeasureSpec.AT_MOST:
heightSize = dpToPx(MIN_SIZE_DEFAULT);
break;
}
int minSize = Math.min(widthSize, heightSize);
//Update measured dimension.
setMeasuredDimension(minSize, minSize);
}
@Override
protected void onDraw(Canvas canvas) {
//Canvas circle image.
drawCircleImage(canvas);
}
/**
* Draw circle image with paint PorterDuff.
*
* @param canvas
* canvas.
*/
private void drawCircleImage(Canvas canvas) {
//Save layer with parameter.
canvas.saveLayerAlpha(getLeft(), getTop(), getRight(), getBottom(), 200);
//Get drawable source.
Drawable drawable = getDrawable();
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Bitmap bitmap = bitmapDrawable.getBitmap();
//Computer circle image radius.
float radiusX = (getWidth() - getPaddingLeft() - getPaddingRight()) / 2f;
float radiusY = (getHeight() - getPaddingTop() - getPaddingBottom()) / 2f;
float radius = Math.min(radiusX, radiusY);
//Computer
Rect rectF = new Rect();
rectF.left = getLeft() + getPaddingLeft();
rectF.top = getTop() + getPaddingTop();
rectF.right = getRight() - getPaddingRight();
rectF.bottom = getBottom() - getPaddingBottom();
int targetBitmapWidth = rectF.right - rectF.left;
int targetBitmapHeight = rectF.bottom - rectF.top;
int diameter = (int) (radius * 2 + 0.5);
float circleX = getPaddingLeft() + radius;
float circleY = getPaddingTop() + radius;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, targetBitmapWidth, targetBitmapHeight, false);
/*
Draw destination bitmap.
*/
Bitmap bitmapDestination = Bitmap.createBitmap(targetBitmapWidth, targetBitmapHeight, Bitmap.Config.ARGB_8888);
Canvas canvasDestination = new Canvas(bitmapDestination);
//Draw circle.
canvasDestination.drawCircle(circleX, circleY, radius, mDrawablePaint);
//Draw destination bitmap.
canvas.drawBitmap(bitmapDestination, 0, 0, mDrawablePaint);
/*
Set paint's porterDuffMode
*/
mDrawablePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
/*
Draw source bitmap.
*/
canvas.drawBitmap(scaledBitmap, rectF, rectF, mDrawablePaint);
//Reset mode value.
mDrawablePaint.setXfermode(null);
//Restore.
canvas.restore();
}
private int dpToPx(int dp) {
return (int) (dp * getResources().getDisplayMetrics().density + 0.5);
}
}
* 如果,您认为到这里就万事大吉了,那么很遗憾:请看下图 *
所以,在绘制完成后,切记要加上:
Paint.setXfermode(null);
未完待续。。。