效果截图

image.png

实现原理

对于圆形头像的实现,其实就是对方形图像做某些处理,以达到圆形头像的效果。一般我们会通过Canvas和Paint结合来实现这种效果。

自定义View来实现

因为圆形头像是视觉方面的需求,一般我们会考虑能否从自定义View的角度来解决问题。自定义的核心有两点:视觉和交互。视觉由onMeasure、onLayout、onDraw这三个方法来完成,而交互则是由dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent等这几个方法来控制,只要处理好这几个方法,就能实现形态各异的自定义View了。

方式一 BitmapShader

package com.yds.myapplication;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapShader;

import android.graphics.Canvas;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.Drawable;

import android.util.AttributeSet;

import androidx.appcompat.widget.AppCompatImageView;

/**

* Created by yds

* on 2020/3/10.

*/

public class CircleImageView extends AppCompatImageView {

private int mSize;

private Paint mPaint;

public CircleImageView(Context context) {

this(context,null);

}

public CircleImageView(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

public CircleImageView(Context context,AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init();

}

private void init(){

mPaint = new Paint();

mPaint.setDither(true);

mPaint.setAntiAlias(true);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int width = getMeasuredWidth();

int height = getMeasuredHeight();

mSize = Math.min(width,height); //取宽高的最小值

setMeasuredDimension(mSize,mSize); //设置CircleImageView为等宽高

}

@Override

protected void onDraw(Canvas canvas) {

//获取sourceBitmap,即通过xml或者java设置进来的图片

Drawable drawable = getDrawable();

if (drawable == null) return;

Bitmap sourceBitmap = ((BitmapDrawable)getDrawable()).getBitmap();

if (sourceBitmap != null){

//对图片进行缩放,以适应控件的大小

Bitmap bitmap = resizeBitmap(sourceBitmap,getWidth(),getHeight());

drawCircleBitmapByShader(canvas,bitmap); //利用BitmapShader实现

}

}

private Bitmap resizeBitmap(Bitmap sourceBitmap,int dstWidth,int dstHeight){

int width = sourceBitmap.getWidth();

int height = sourceBitmap.getHeight();

float widthScale = ((float)dstWidth) / width;

float heightScale = ((float)dstHeight) / height;

//取最大缩放比

float scale = Math.max(widthScale,heightScale);

Matrix matrix = new Matrix();

matrix.postScale(scale,scale);

return Bitmap.createBitmap(sourceBitmap,0,0,width,height,matrix,true);

}

private void drawCircleBitmapByShader(Canvas canvas,Bitmap bitmap){

BitmapShader shader = new BitmapShader(bitmap,BitmapShader.TileMode.CLAMP,BitmapShader.TileMode.CLAMP);

mPaint.setShader(shader);

canvas.drawCircle(mSize / 2,mSize /2 ,mSize / 2,mPaint);

}

}

方式二 PorterDuffXfermode

package com.yds.myapplication;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.PorterDuff;

import android.graphics.PorterDuffXfermode;

import android.util.AttributeSet;

import androidx.appcompat.widget.AppCompatImageView;

/**

* Created by yds

* on 2020/3/10.

*/

public class CircleImageViewPD extends AppCompatImageView {

private int mWidth;

private int mHeight;

private Paint mPaint;

private Bitmap CircleBitmap;

public CircleImageViewPD(Context context) {

super(context);

}

public CircleImageViewPD(Context context, AttributeSet attrs) {

super(context, attrs);

}

public CircleImageViewPD(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

private void ImgCircle(){

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

paint.setAntiAlias(true);

paint.setFilterBitmap(true);

paint.setColor(Color.GRAY);

paint.setStrokeWidth(5);

paint.setStyle(Paint.Style.FILL);

CircleBitmap = Bitmap.createBitmap(mWidth,mHeight, Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(CircleBitmap);

canvas.drawCircle(mWidth/2,mHeight/2,mWidth/2,paint);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

mWidth = getMeasuredWidth();

mHeight = getMeasuredHeight();

mPaint = new Paint();

mPaint.setAntiAlias(true);

mPaint.setFilterBitmap(true);

ImgCircle();

}

@Override

protected void onDraw(Canvas canvas) {

int count = canvas.saveLayerAlpha(0, 0, mWidth, mHeight, 250, Canvas.ALL_SAVE_FLAG);

super.onDraw(canvas);

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

canvas.drawBitmap(CircleBitmap,0,0, mPaint);

canvas.restoreToCount(count);

}

}

方式三 继承自Drawable

package com.yds.myapplication;

import android.graphics.Bitmap;

import android.graphics.BitmapShader;

import android.graphics.Canvas;

import android.graphics.ColorFilter;

import android.graphics.Paint;

import android.graphics.PixelFormat;

import android.graphics.Shader;

import android.graphics.drawable.Drawable;

/**

* Created by yds

* on 2020/3/10.

*/

public class CircleImageViewDrawable extends Drawable {

private Paint mPaint;

private BitmapShader mBitmapShader;

private int mSize;

private int mRadius;

public CircleImageViewDrawable(Bitmap bitmap){

mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);

mPaint.setShader(mBitmapShader);

mSize = Math.min(bitmap.getWidth(),bitmap.getHeight());

mRadius = mSize/2;

}

@Override

public void draw(Canvas canvas) {

canvas.drawCircle(mRadius,mRadius,mRadius,mPaint);

}

@Override

public void setAlpha(int alpha) {

mPaint.setAlpha(alpha);

}

@Override

public void setColorFilter(ColorFilter colorFilter) {

mPaint.setColorFilter(colorFilter);

}

@Override

public int getOpacity() {

return PixelFormat.TRANSLUCENT;

}

@Override

public int getIntrinsicHeight() {

return mSize;

}

@Override

public int getIntrinsicWidth() {

return mSize;

}

}

使用

public class MainActivity extends AppCompatActivity {

private ImageView mImageView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mImageView = findViewById(R.id.img);

Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.img);

Drawable drawable = new CircleImageViewDrawable(bitmap);

mImageView.setImageDrawable(drawable);

}

}

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context=".MainActivity">

android:id="@+id/img"

android:layout_width="120dp"

android:layout_height="120dp" />

android:layout_width="120dp"

android:layout_height="120dp"

android:src="@drawable/img"/>

android:layout_width="120dp"

android:layout_height="120dp"

android:src="@drawable/img"/>

android 头像球_Android实现圆形头像效果相关推荐

  1. Android实现带圆环的圆形头像(转载)

    其实设置圆头像很交单,一行代码: Glide.with(mContext).load("url").centerCrop().into(binding.supermarketIvH ...

  2. android 头像球_Android一行代码实现圆形头像

    效果图 在开发APP中,经常要实现圆形头像,那么该如何实现呢? 要裁剪吗,要重写draw函数吗?不用,只用一行代码就可以实现 Glide实现圆形图像 Glide.with(mContext) .loa ...

  3. android圆环头像,Android实现带圆环的圆形头像

    在最近写的一个天气APP中用到了圆形头像这样的一个样式,中间是圆形的头像(被圆形切割的图片),周围是一个带颜色的圆环.如下图所示,今天就来说一所它的实现过程. 它的实现也不是特别困难,其实就是用到了B ...

  4. android头像圆环,Android实现带圆环的圆形头像

    在最近写的一个天气APP中用到了圆形头像这样的一个样式,中间是圆形的头像(被圆形切割的图片),周围是一个带颜色的圆环.如下图所示,今天就来说一所它的实现过程. 它的实现也不是特别困难,其实就是用到了B ...

  5. ios 裁剪圆形头像_IOS_iOS如何裁剪圆形头像,本文实例为大家介绍了iOS裁剪 - phpStudy...

    iOS如何裁剪圆形头像 本文实例为大家介绍了iOS裁剪圆形头像的详细代码,供大家参考,具体内容如下 - (void)viewDidLoad { [super viewDidLoad]; //加载图片 ...

  6. 圆形头像 android,android 一个简单的实现圆形头像的Demo

    [实例简介] [实例截图] [核心代码] package davidzoomimageviewrounddemo.qq986945193.com.davidzoomimageviewrounddemo ...

  7. ios 裁剪圆形头像_iOS中裁剪圆形头像

    - (void)clipImage { // 0.加载图片 UIImage *image = [UIImage imageNamed:@"阿狸头像"]; // 1.开启位图上下文, ...

  8. android 开源 高斯模糊_Android实现带毛玻璃效果(高斯模糊)背景的Dialog

    最近换了工作,由于工作中要使用一些自己以前不是很了解的知识,就没有时间更新博客了. 由于最近做了一些很有意思的小demo,不吐不快,再加上还是认为技术需要沉淀和梳理,所以再次把写博客这件事拾起来. 已 ...

  9. android 辐射动画_Android 四种动画效果的调用实现代码

    (1) main.xml 代码如下:(声明四个按钮控件) XML代码: android:id="@+id/widget32" android:layout_width=" ...

最新文章

  1. linux 打开关闭文件,Linux系统编程-文件打开关闭
  2. 伪mac android,Mac,android sdk,monkey压力测试,真机
  3. Linux部署动态网页,Nginx发布支持动态配置的开源Web服务器
  4. Android开发八 “尚未注册网络”错误信息的解决办法
  5. JS拖拽,移动与拉伸
  6. linux安装mongo卸载mongo,CentOS7安装及卸载MongoDB.md
  7. html可折叠边栏,html – 仅使用CSS的可折叠灵活宽边栏
  8. 基于JAVA+SpringMVC+Mybatis+MYSQL的bbs论坛管理系统
  9. oracle关闭多余游标,关闭结果集后,Oracle不删除游标
  10. java人脸识别怎么写-------源码附上
  11. 分数间隔 matlab,分数间隔均衡器
  12. python怎么全部注释_python全部注释
  13. Java支付宝APP支付-统一收单交易退款
  14. 域名转入需要经过“命名审核”状态
  15. 秘密:从程序员到领导者的微妙之处
  16. 计算机打字盲打方法,盲打
  17. 被删除的pip,重新安装
  18. 5.[STM32]动动小手,自己制作做一个自动浇花系统吧
  19. AcWing每日一题 3565.完美矩阵(绝对值不等式)
  20. apds9960第三方用户库实现

热门文章

  1. ImageView详解
  2. 关于MySQL自增id不连续问题
  3. Mac技巧|如何高效使用苹果便笺?利用便笺快捷键快速完成操作!
  4. idea java连接MongoDB(1)——前置配置
  5. PHP快速推送微信模板消息
  6. java 随机生成6位邀请码、不重复
  7. checkbox多选框,indeterminate 状态
  8. 使用Spark SQL 探索“全国失信人数据”
  9. HIVE源码阅读(五)
  10. windows10的PHP环境变量