其实设置圆头像很交单,一行代码:
Glide.with(mContext).load("url").centerCrop().into(binding.supermarketIvHead)
也可以使用下面这个文章的方法:
转载原文链接:https://www.zhangshengrong.com/p/9MNlDbGnNJ/
效果图:
废话少说,上代码:
mainActivity.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<com.example.myapplication.CircleWeather
android:layout_width="250dp"
android:layout_height="wrap_content"
android:id="@+id/circleWeather"
android:layout_centerHorizontal="true" />
</LinearLayout>
MainActivity.java:
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import cn.jzvd.JzvdStd;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
CircleWeather.java:
package com.example.myapplication;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
public class CircleWeather extends View {
private int widthSize;
private int heightSize;
private Paint mpaint1,mpaint2,mpaint3;
private Bitmap mbitmap;
private BitmapShader mbitmapshader;
public CircleWeather(Context context) {
super(context);
}
public CircleWeather(Context context, AttributeSet attributeSet){
super(context,attributeSet);
initView();
}
private void initView(){
mpaint1=new Paint();
mpaint2=new Paint();
mpaint3=new Paint();
mpaint2.setStyle(Paint.Style.FILL);
mpaint3.setStyle(Paint.Style.FILL);
mpaint2.setAntiAlias(true);
mpaint3.setAntiAlias(true);
mpaint2.setColor(getResources().getColor(R.color.purple_200));
mpaint3.setColor(getResources().getColor(R.color.teal_700));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
widthSize=MeasureSpec.getSize(widthMeasureSpec);
heightSize=widthSize;
setMeasuredDimension(widthSize,heightSize);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
// 获得要画圆环的图片
mbitmap= BitmapFactory.decodeResource(getResources(),R.mipmap.presale_head_portrait);//bitmapshader只能在onDraw中实现在外部不可以
int BitmapWidthSize=mbitmap.getWidth();
int BitmapHeightSize=mbitmap.getHeight();
float scale=(float)widthSize/Math.min(BitmapHeightSize,BitmapWidthSize);//获取最为合适的尺寸
Matrix matrix=new Matrix();
matrix.setScale(scale,scale);
Bitmap bitmap=Bitmap.createBitmap(mbitmap,0,0,BitmapWidthSize,BitmapHeightSize,matrix,true);
mbitmapshader=new BitmapShader(bitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
mpaint1.setShader(mbitmapshader);
canvas.drawCircle((float)widthSize*0.5f,(float)heightSize*0.5f,(float)heightSize*0.5f,mpaint2);
canvas.drawCircle((float)widthSize*0.5f,(float)heightSize*0.5f,(float)heightSize*0.47f,mpaint3);
canvas.drawCircle((float)widthSize*0.5f,(float)heightSize*0.5f,(float)heightSize*0.47f,mpaint1);
super.onDraw(canvas);
}
}
然后,一个带有圆环的头像就画好了。图片的话,自己准备,我也是随便找的图片,实现这个效果就行。
该方案转载自:Android实现带圆环的圆形头像 / 张生荣
方法二:
除了上面的方法外,还可以利用Glide框架来实现:
CornerTransform cornerTransform = new CornerTransform(mContext, 12f);
cornerTransform.setNeedCorner(true, true ,false, false);//左上角、右上角设置为圆角12dp
Glide.with(mContext).load("https://img0.baidu.com/it/u=2953940086,3621245794&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500")
.transform(cornerTransform).into(binding.supermarketIvHead);
CornerTransform.java:
package com.example.view.view;
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.RectF;
import android.graphics.Shader;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapResource;
import java.security.MessageDigest;
/**
* 自定义图片的4个圆角、或者部分圆角
*/
public class CornerTransform implements Transformation<Bitmap> {
private BitmapPool mBitmapPool;
private float radius;
private boolean isLeftTop, isRightTop, isLeftBottom, isRightBotoom;
/**
* 需要设置圆角的部分
*
* @param leftTop 左上角
* @param rightTop 右上角
* @param leftBottom 左下角
* @param rightBottom 右下角
*/
public void setNeedCorner(boolean leftTop, boolean rightTop, boolean leftBottom, boolean rightBottom) {
isLeftTop = leftTop;
isRightTop = rightTop;
isLeftBottom = leftBottom;
isRightBotoom = rightBottom;
}
/**
* @param context 上下文
* @param radius 圆角幅度
*/
public CornerTransform(Context context, float radius) {
this.mBitmapPool = Glide.get(context).getBitmapPool();
this.radius = radius;
}
@NonNull
@Override
public Resource<Bitmap> transform(@NonNull Context context, @NonNull Resource<Bitmap> resource, int outWidth, int outHeight) {
Bitmap source = resource.get();
int finalWidth, finalHeight;
//输出目标的宽高或高宽比例
float scale;
if (outWidth > outHeight) {
//如果 输出宽度 > 输出高度 求高宽比
scale = (float) outHeight / (float) outWidth;
finalWidth = source.getWidth();
//固定原图宽度,求最终高度
finalHeight = (int) ((float) source.getWidth() * scale);
if (finalHeight > source.getHeight()) {
//如果 求出的最终高度 > 原图高度 求宽高比
scale = (float) outWidth / (float) outHeight;
finalHeight = source.getHeight();
//固定原图高度,求最终宽度
finalWidth = (int) ((float) source.getHeight() * scale);
}
} else if (outWidth < outHeight) {
//如果 输出宽度 < 输出高度 求宽高比
scale = (float) outWidth / (float) outHeight;
finalHeight = source.getHeight();
//固定原图高度,求最终宽度
finalWidth = (int) ((float) source.getHeight() * scale);
if (finalWidth > source.getWidth()) {
//如果 求出的最终宽度 > 原图宽度 求高宽比
scale = (float) outHeight / (float) outWidth;
finalWidth = source.getWidth();
finalHeight = (int) ((float) source.getWidth() * scale);
}
} else {
//如果 输出宽度=输出高度
finalHeight = source.getHeight();
finalWidth = finalHeight;
}
//修正圆角
this.radius *= (float) finalHeight / (float) outHeight;
Bitmap outBitmap = this.mBitmapPool.get(finalWidth, finalHeight, Bitmap.Config.ARGB_8888);
if (outBitmap == null) {
outBitmap = Bitmap.createBitmap(finalWidth, finalHeight, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(outBitmap);
Paint paint = new Paint();
//关联画笔绘制的原图bitmap
BitmapShader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//计算中心位置,进行偏移
int width = (source.getWidth() - finalWidth) / 2;
int height = (source.getHeight() - finalHeight) / 2;
if (width != 0 || height != 0) {
Matrix matrix = new Matrix();
matrix.setTranslate((float) (-width), (float) (-height));
shader.setLocalMatrix(matrix);
}
paint.setShader(shader);
paint.setAntiAlias(true);
RectF rectF = new RectF(0.0F, 0.0F, (float) canvas.getWidth(), (float) canvas.getHeight());
//先绘制圆角矩形
canvas.drawRoundRect(rectF, this.radius, this.radius, paint);
//左上角圆角
if (!isLeftTop) {
canvas.drawRect(0, 0, radius, radius, paint);
}
//右上角圆角
if (!isRightTop) {
canvas.drawRect(canvas.getWidth() - radius, 0, canvas.getWidth(), radius, paint);
}
//左下角圆角
if (!isLeftBottom) {
canvas.drawRect(0, canvas.getHeight() - radius, radius, canvas.getHeight(), paint);
}
//右下角圆角
if (!isRightBotoom) {
canvas.drawRect(canvas.getWidth() - radius, canvas.getHeight() - radius, canvas.getWidth(), canvas.getHeight(), paint);
}
return BitmapResource.obtain(outBitmap, this.mBitmapPool);
}
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
}
}
方法三:
除了利用Glide框架外,还可以自定义ImageView来实现:
RoundImageView.java:
/*
// 需要添加到一下配置到 .../res/values/attrs.xml
<!-- 适用于 自定义 ***.widget.roundangle 圆角控件 -->
<declare-styleable name="roundView">
<attr name="radius" format="dimension"/>
</declare-styleable>
*/
package com.example.view.view;
import android.content.Context;
import android.content.res.TypedArray;
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.util.AttributeSet;
import androidx.appcompat.widget.AppCompatImageView;
import com.example.common.util.DisplayUtil;
import com.example.view.R;
/** 圆角图片控件 */
public class RoundImageView extends AppCompatImageView {
private float radius; // 半径,单位像素
private RectF rectF;
private Paint zonePaint;
private Paint maskPaint;
private int type;
/** 设置半径 【radius = 半径;单位PX】 */
public void setRadius(int radius) {
setRadius(radius, true);
}
/** 设置半径 【radius = 半径;单位PX】【isInvalidate = 是否刷新View】 */
public void setRadius(int radius, boolean isInvalidate) {
this.radius = radius;
this.rectF = null;
this.zonePaint = null;
this.maskPaint = null;
if (isInvalidate)
invalidate();
}
public RoundImageView(Context context, int radius) {
super(context);
this.radius = radius;
}
public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
/** 初始化样式参数 */
private void init(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
this.radius = (int) typedArray.getDimension(R.styleable.RoundImageView_radius_size, DisplayUtil.dip2px(context,12));
type = typedArray.getInt(R.styleable.RoundImageView_type,0);
typedArray.recycle();
}
@Override
public void draw(Canvas canvas) {
if (rectF == null || zonePaint == null || maskPaint == null) {
rectF = new RectF();
zonePaint = new Paint();
maskPaint = new Paint();
rectF.set(0, 0, getWidth(), getHeight());
zonePaint.setAntiAlias(true);
zonePaint.setColor(Color.WHITE);
maskPaint.setAntiAlias(true);
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
}
canvas.saveLayer(rectF, zonePaint, Canvas.ALL_SAVE_FLAG);
canvas.drawRoundRect(rectF, radius, radius, zonePaint);
setType(canvas);
canvas.saveLayer(rectF, maskPaint, Canvas.ALL_SAVE_FLAG);
super.draw(canvas);
}
private void setType(Canvas canvas){
if(type == 1){
canvas.drawRect(0,0,radius,radius,zonePaint); //左上角
canvas.drawRect(rectF.right - radius,0,rectF.right,radius,zonePaint); //右上角
}else if(type == 2){
canvas.drawRect(0,rectF.bottom - radius,radius,rectF.bottom,zonePaint); //左下角
canvas.drawRect(rectF.right - radius,rectF.bottom - radius,rectF.right,rectF.bottom,zonePaint); //右下角
}
}
}
<com.example.view.view.RoundImageView
app:radius_size="12dp" //12dp圆角
app:type="bottom" //左上角、右上角为圆角
android:layout_width="match_parent"
android:layout_height="173dp"
android:scaleType="fitXY"
android:id="@+id/supermarket_iv_head"/>