圆角、圆形ImageView(头像需求)

在网上找了几个,都只是圆形的,或多或少也都存在一些问题,比如用xutils加载图片时就因为transitationdrawable导致图片不显示问题,自己就改了一下,以下是代码

很简单,具体效果和xml'中定义的shape一样,就不具体讲解了

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.TransitionDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.net.Uri;
import android.util.AttributeSet;
import android.widget.ImageView;

public class CircleImageView extends ImageView {
	// 随便设一个值就好
	private final int DEFAULT_WIDTH = 10;

	private Bitmap mBitmap;
	/** 图片转换后的drawable **/
	private ShapeDrawable circleDrawable;
	/** 边框转换后的drawable **/
	private ShapeDrawable borderDrawable;

	/** 图像的四角圆弧半径,当设置为-1时或者大于图片显示大小一半时,则会显示为圆形 **/
	private float circleRadiu;
	/** 边框颜色 **/
	private int borderColor = Color.BLUE;
	/** 边框大小 **/
	private int borderWidth;

	private boolean isCircle;

	public CircleImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		if (getDrawable() == null || getDrawable().getIntrinsicWidth() == 0
				|| getDrawable().getIntrinsicHeight() == 0) {
			return;
		}
		if (borderDrawable != null) {
			borderDrawable.draw(canvas);
		}
		if (circleDrawable != null) {
			canvas.save();
			canvas.translate(borderWidth, borderWidth);
			circleDrawable.draw(canvas);
			canvas.restore();
		}
	}

	@Override
	public void setImageBitmap(Bitmap bm) {
		super.setImageBitmap(bm);
		mBitmap = bm;
		initDrawable();
	}

	@Override
	public void setImageDrawable(Drawable drawable) {
		super.setImageDrawable(drawable);
		mBitmap = getBitmapFromDrawable(drawable);
		initDrawable();
	}

	@Override
	public void setImageResource(int resId) {
		super.setImageResource(resId);
		mBitmap = getBitmapFromDrawable(getDrawable());
		initDrawable();
	}

	@Override
	public void setImageURI(Uri uri) {
		super.setImageURI(uri);
		mBitmap = getBitmapFromDrawable(getDrawable());
		initDrawable();
	}

	/***
	 * 生成边框和圆角图片drawable
	 */
	private void initDrawable() {
		if (mBitmap == null || mBitmap.getWidth() == 0
				|| mBitmap.getHeight() == 0) {
			return;
		}
		// 当角半径设置为-1时,并且控件要求显示的大小为正方形,则图片和边框显示后的效果为圆形
		if (isCircle) {
			if (getWidth() != 0 && getHeight() != 0
					&& getWidth() == getHeight()) {
				circleRadiu = getWidth();
			} else {
				circleRadiu = 0;
			}
		}

		initBorderDrawable();
		initCircleDrawable();

		invalidate();

	}

	/***
	 * 生成边框Drawalbe
	 */
	private void initBorderDrawable() {
		// 当边框大小不为0时,进行边框的生成转换
		if (borderWidth != 0) {
			// 如果角半径不为0,则边框的角半径应该加上边框的大小
			float borderRadiu = circleRadiu == 0 ? 0 : circleRadiu
					+ borderWidth;
			// 设置四角半径集合
			float[] borderRadius = new float[] { borderRadiu, borderRadiu,
					borderRadiu, borderRadiu, borderRadiu, borderRadiu,
					borderRadiu, borderRadiu };
			borderDrawable = new ShapeDrawable(new RoundRectShape(borderRadius,
					null, null));
			borderDrawable.getPaint().setColor(borderColor);
			borderDrawable.getPaint().setAntiAlias(true);
			// 设置边框显示大小
			borderDrawable.setBounds(0, 0, getWidth(), getHeight());
		}
	}

	/***
	 * 生成圆角图片drawable
	 */
	private void initCircleDrawable() {
		float[] circleRadius = new float[] { circleRadiu, circleRadiu,
				circleRadiu, circleRadiu, circleRadiu, circleRadiu,
				circleRadiu, circleRadiu };
		// 图片显示的大小范围应该是图片进行放大或缩小后的控件要求的大小
		int boundWidth = (int) ((float) getWidth() - borderWidth * 2);
		int boundHeight = (int) ((float) getHeight() - borderWidth * 2);

		circleDrawable = new ShapeDrawable(new RoundRectShape(circleRadius,
				null, null));
		BitmapShader bitmapShader = new BitmapShader(mBitmap,
				Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
		circleDrawable.getPaint().setShader(bitmapShader);
		circleDrawable.setBounds(0, 0, boundWidth, boundHeight);

		// 将图片进行放大或缩小适应控件大小
		if (getWidth() != 0 && getHeight() != 0) {
			Matrix matrix = new Matrix();
			matrix.setScale(((float) boundWidth) / mBitmap.getWidth(),
					((float) boundHeight) / mBitmap.getHeight());
			bitmapShader.setLocalMatrix(matrix);
		}

	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		// TODO Auto-generated method stub
		super.onSizeChanged(w, h, oldw, oldh);
		initDrawable();
	}

	private Bitmap getBitmapFromDrawable(Drawable drawable) {
		if (drawable == null) {
			return null;
		}

		if (drawable instanceof TransitionDrawable) {
			Drawable tdrawable = ((TransitionDrawable) drawable).getDrawable(1);
			if (tdrawable != null) {
				drawable = tdrawable;
			}
		}
		
		if (drawable instanceof BitmapDrawable) {
			return ((BitmapDrawable) drawable).getBitmap();
		}


		try {
			Bitmap bitmap;
			if (drawable instanceof ColorDrawable) {
				bitmap = Bitmap.createBitmap(DEFAULT_WIDTH, DEFAULT_WIDTH,
						Bitmap.Config.ARGB_8888);
			} else {
				bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
						drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
			}

			Canvas canvas = new Canvas(bitmap);
			drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
			drawable.draw(canvas);
			return bitmap;
		} catch (Exception e) {
			return null;
		}
	}

	/***
	 * 设置角半径
	 * 
	 * @param circleRadiu
	 *            当角半径设置为-1时,并且控件大小为正方形,则图片和边框显示后的效果为圆形
	 *            如果半径小于正方形大小的一半,则会显示圆角矩形,超过一半,则为圆形
	 */
	public void setCircleRadiu(float circleRadiu) {
		if (circleRadiu == -1) {
			isCircle = true;
			circleRadiu = 0;
		} else {
			isCircle = false;
		}
		this.circleRadiu = circleRadiu;
		initDrawable();
	}

	/***
	 * 设置边框颜色
	 * 
	 * @param borderColor
	 */
	public void setBorderColor(int borderColor) {
		this.borderColor = borderColor;
		initDrawable();
	}

	/***
	 * 设置边框大小
	 * 
	 * @param borderWidth
	 */
	public void setBorderWidth(int borderWidth) {
		this.borderWidth = borderWidth;
		initDrawable();
	}

	public void setCircle(boolean isCircle) {
		this.isCircle = isCircle;
	}

	@Override
	protected void onDetachedFromWindow() {
		// TODO Auto-generated method stub
		if (mBitmap != null) {
			mBitmap.recycle();
			mBitmap = null;
		}
		super.onDetachedFromWindow();
	}
}


以下是效果图
          

     


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值