自定义 View:如何手动绘制一个头像控件
发布于: 1 小时前
1.知识点
Xfermode:为了把多次绘制进行「合成」,例如蒙版效果:用 A 的形状和 B 的图案
从一张图片里面截取指定宽度的方法,等比例缩放
Bitmap getAvatar(int width, int resId){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), resId, options);
options.inJustDecodeBounds = false;
options.inDensity = options.outWidth; // 原始宽度
options.inTargetDensity = width; // 目标宽度,由于inScaled默认为true,因此 会自动按照目标宽度/原始宽度的尺寸缩放
return BitmapFactory.decodeResource(getResources(), resId, options);
}
复制代码
2.原理
3.代码
package com.example.hellojnicallback;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Xfermode;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
public class AvatarView extends View {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private static final float WIDTH = Util.dp2px(300);
private static final float PADDING = Util.dp2px(40);
private static final float EDGE_WIDTH = Util.dp2px(10);
Bitmap bitmap;
Xfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
public AvatarView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
Bitmap destinationImage;
Bitmap sourceImage;
RectF rectf = new RectF();
{
bitmap = getAvatar((int) WIDTH, R.drawable.xie);
sourceImage = getAvatar((int) WIDTH, R.drawable.inforec);
destinationImage = getAvatar((int) WIDTH, R.drawable.xie);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
rectf.set(PADDING, PADDING, PADDING+WIDTH, PADDING+WIDTH);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawOval(PADDING, PADDING, PADDING+WIDTH, PADDING+WIDTH, paint);
int saved = canvas.saveLayer(rectf, paint); // 离屏缓冲
canvas.drawOval(PADDING+EDGE_WIDTH, PADDING+EDGE_WIDTH, PADDING+WIDTH-EDGE_WIDTH, PADDING+WIDTH-EDGE_WIDTH, paint);
// paint.setXfermode(xfermode);
//
// canvas.drawBitmap(bitmap, PADDING, PADDING, paint);
// paint.setXfermode(null);
// canvas.saveLayer();
// canvas.drawBitmap(destinationImage, PADDING, PADDING, paint);
paint.setXfermode(xfermode);
canvas.drawBitmap(sourceImage, PADDING, PADDING, paint);
paint.setXfermode(null);
canvas.restoreToCount(saved);
}
Bitmap getAvatar(int width, int resId){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), resId, options);
options.inJustDecodeBounds = false;
options.inDensity = options.outWidth;
options.inTargetDensity = width;
return BitmapFactory.decodeResource(getResources(), resId, options);
}
}
复制代码
划线
评论
复制
发布于: 1 小时前阅读数: 3
版权声明: 本文为 InfoQ 作者【Changing Lin】的原创文章。
原文链接:【http://xie.infoq.cn/article/c45345a2ae218c859576ceedc】。文章转载请联系作者。
Changing Lin
关注
获得机遇的手段远超于固有常规之上~ 2020.04.29 加入
我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。
评论