自定义 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 加入
我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。











评论