Android如何自定义View绘制圆形头像功能
创始人
2024-12-22 17:21:28
0次

自定义RoundImageView继承自ImageView

public class RoundImageView extends ImageView {  public RoundImageView(Context context) {    super(context);  }  public RoundImageView(Context context, @Nullable AttributeSet attrs) {    super(context, attrs);  }  public RoundImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);  }}

不知你是否注意过每当我们继承自View的时候,系统都会提示我们覆盖重写4个构造方法,这里我们只覆盖了三个,然后就开始在每个构造方法中进行初始化,那么,是不是每次都会调用所有的构造方法呢,如果不是,这三个构造方法又会什么时候调用呢?下面我们来通过例子来验证。

使用自定义View无非就两种情况下,第一种就是直接在xml布局中使用,另一种就是在Activity中new出来,下面我们分别使用上述两种方式,为了便于观察我们在三个构造方法中分别加入一行打印。

首先我们在xml直接使用,运行打印如下:

com.example.roundimageview D/RoundImageView: RoundImageView: 两个参数的构造方法

然后我们在Activity中,new一个RoundImageView

roundImageView = RoundImageView(this@MainActivity)roundImageView = RoundImageView(this@MainActivity, null)roundImageView = RoundImageView(this@MainActivity, null,0)

运行打印日志如下:

结论:自定义View当在xml中使用,使用的是第二个构造方法,当在Activity中使用时,实例化时传入几个参数调用的就是含有几个参数的构造方法。

实现圆形头像的思想

我始终认为自定义View的难度只在于它的实现思想,通常我们遇到问题的时候,并不是Google不到,而是压根就不知道这个问题该去如何Google,如果知道了问题所产生的原因,其实问题已经迎刃而解了,最怕的是不知道问题为什么会产生。

实现圆形头像的思想一个简单的图就可以表示了。

矩形区域是完整的图片,圆形区域就是我们最终显示的头像区域,那么就很简单了,圆形区域与矩形区域相交,取并集区域?在矩形中画一个与矩形长或宽相切的圆,而圆的直径是长或宽较短的一边。

编码实现

获取原有头像的bitmap

首先我们需要获取设置头像的bitmap,我们可以直接通过API来获取设置的图片资源,

drawable = this.getDrawable();

再将图片资源转化为bitmap

首先我们判断drawable是否为空,如果为空说明用户没有设置,抛出资源未找到的异常。

if (drawable == null) {  throw new Resources.NotFoundException("Image resource not set");}

如果不为空,我们创建一个与图片资源大小相等的bitmap,并将bitmap绘制出来,代码如下所示:

bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),    Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),    drawable.getIntrinsicHeight());drawable.draw(canvas);

绘制圆形bitmap

通过上面的代码,我们得到了原有的bitmap图像,紧接着我们需要绘制圆形的bitmap,与上面类似,首先创建一个和bitmap大小一致的位图

circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);

我们画一个与bitmap等大的矩形

Paint paint = new Paint();Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());canvas.drawRect(rect,paint);RectF rectF = new RectF(rect);

将较短的一边设置圆的半径

float roundRa = 0.0f;if (bitmap.getWidth() > bitmap.getHeight()) {  roundRa = bitmap.getHeight() / 2.0f;} else {  roundRa = bitmap.getWidth() / 2.0f;}

设置paint和canvas属性

paint.setAntiAlias(true);canvas.drawARGB(0, 0, 0, 0);paint.setColor(Color.WHITE);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

canvas.drawARGB将绘制裁剪设为透明,paint.setXfermode中的PorterDuffXfermode类很强大,后面我们会单独一篇文章讲解。

最终我们重新将bitmap绘制出来即可

canvas.drawBitmap(bitmap, rect, rect, paint);

绘制部分完整代码如下所示:

* 获取圆形裁剪的bitmap * * @param bitmap 原bitmap */private Bitmap getCircleBitmap(Bitmap bitmap) {  circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);  Canvas canvas = new Canvas(circleBitmap);  Paint paint = new Paint();  Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());  RectF rectF = new RectF(rect);  float roundRa = 0.0f;  if (bitmap.getWidth() > bitmap.getHeight()) {    roundRa = bitmap.getHeight() / 2.0f;  } else {    roundRa = bitmap.getWidth() / 2.0f;  }  paint.setAntiAlias(true);  canvas.drawARGB(0, 0, 0, 0);  paint.setColor(Color.GRAY);  canvas.drawRoundRect(rectF, roundRa, roundRa, paint);  paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));  canvas.drawBitmap(bitmap, rect, rect, paint);  return circleBitmap;}

设置最终的bitmap

得到bitma后我们直接重新设置即可显示

setImageBitmap(getCircleBitmap(bitmap));

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...