android:圆形、圆角图片

当我们涉及到头像的时候,一般会用到圆形或者圆角的图片,以下是继承ImageView实现的圆形圆角图片。

1.自定义属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="RoundImageView">
        <attr name="outer_border_width" format="dimension" /> <!-- 边框宽度 -->
        <attr name="outer_border_color" format="color" />     <!-- 边框颜色 -->
        <attr name="corner_angle" format="dimension" />       <!-- 圆角大小 -->
        <attr name="show_type">								  <!-- 图片类型 -->
            <enum name="circle" value="0" />				  <!-- 圆形图片 -->
            <enum name="round" value="1" />					  <!-- 圆角图片-->
        </attr>
    </declare-styleable>

</resources>

2.RoundImageView的实现方法:

package com.example.roundimagedemo;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.widget.ImageView;

public class RoundImageView extends ImageView{
	
	private static final String TAG = RoundImageView.class.getSimpleName();
	
	/**
	 * 外部边框的宽和颜色 
	 */
	private static final int DEFAULT_OUTER_BORDER_WIDTH = 0;
    private static final int DEFAULT_OUTER_BORDER_COLOR = Color.TRANSPARENT;
	private int outerWidth = DEFAULT_OUTER_BORDER_WIDTH;
	private int outerColor = DEFAULT_OUTER_BORDER_COLOR;
    
	private static final int COLORDRAWABLE_DIMENSION = 1;
	
	/**
	 * 显示图片的类型
	 */
	private static final int TYPE_CIRCLE = 0;
	private static final int TYPE_ROUND = 1;
	private int showType = TYPE_CIRCLE;
	
	/**
	 * 圆角大小的默认值 
	 */
	private static final int DEFAULT_CORNER_ANGLE = 10;
	
	/**
	 * 圆角实际大小值 
	 */
	private int mCornerAngle = 0;
	
	/**
	 * 圆形图片时候半径大小 
	 */
	private int mCircleRadius = 0;
	
	/**
	 * 绘图画笔paint 
	 */
	private Paint mBitmapPaint = null;
	private Paint mOuterPaint = null;
	
	
	/**
	 * 3X3缩小放大矩阵 
	 */
	private Matrix mMatrix = null;
	
	/**
	 * 渲染图像,为绘制图形着色 
	 */
	private BitmapShader mBitmapShader = null;
	
	/**
	 * 大小 
	 */
	private int mCircleViewWidth = 0;
	private RectF mDrawableRectF = null;
	private RectF mOuterRectF = null;
	
	public RoundImageView(Context context) {
		this(context, null);
	}
	
	public RoundImageView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}
	
	public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(attrs);
	}
	
	/**
	 * 初始化操作 
	 */
	private void init(AttributeSet attrs){
		
		TypedArray ta = getContext().obtainStyledAttributes(attrs,R.styleable.RoundImageView);
		
		showType = ta.getInt(R.styleable.RoundImageView_show_type, TYPE_CIRCLE);
		mCornerAngle = ta.getDimensionPixelSize(R.styleable.RoundImageView_corner_angle, dp2px());
		outerWidth = ta.getDimensionPixelSize(R.styleable.RoundImageView_outer_border_width, DEFAULT_OUTER_BORDER_WIDTH);
		outerColor = ta.getColor(R.styleable.RoundImageView_outer_border_color, DEFAULT_OUTER_BORDER_COLOR);
		
		ta.recycle();
		
		mMatrix = new Matrix();
		
		mBitmapPaint = new Paint();
		mBitmapPaint.setAntiAlias(true);
		
		mOuterPaint = new Paint();
		mOuterPaint.setStyle(Paint.Style.STROKE);
		mOuterPaint.setAntiAlias(true);
		mOuterPaint.setColor(outerColor);
		mOuterPaint.setStrokeWidth(outerWidth);
		
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		/**
		 * 测量的时候,如果获取的类型是圆形的,则强制把view的宽高设为相同大小,以小的为标准 
		 */
		if(showType == TYPE_CIRCLE){
			mCircleViewWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
			mCircleRadius = mCircleViewWidth / 2 - outerWidth / 2;
			setMeasuredDimension(mCircleViewWidth, mCircleViewWidth);
		}
	}
	
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		/**
		 * 圆角图片的范围 
		 */
		if(showType == TYPE_ROUND){
			mOuterRectF = new RectF(0,0,getWidth(),getHeight());
			mDrawableRectF = new RectF(outerWidth,outerWidth,getWidth()-outerWidth,getHeight()-outerWidth);
		}
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		Drawable drawable = getDrawable();
		if(drawable == null){
			Log.i(TAG, "[null] drawable is null.");
			return;
		}
		setShader(getBitmapFromDrawable(drawable));
		switch (showType) {
		case TYPE_CIRCLE:
			canvas.drawCircle(getWidth()/2, getHeight()/2, mCircleRadius, mBitmapPaint);
			canvas.drawCircle(getWidth()/2, getHeight()/2, mCircleRadius, mOuterPaint);
			break;

		case TYPE_ROUND:
			canvas.drawRoundRect(mDrawableRectF, mCornerAngle, mCornerAngle, mBitmapPaint);
			canvas.drawRoundRect(mOuterRectF, mCornerAngle, mCornerAngle, mOuterPaint);
			break;
		}
	}
	
	/**
	 * 初始化BitmapShader 
	 */
	private void setShader(Bitmap mBitmap){
		
		if(mBitmap == null){
			Log.i(TAG, "[null] mBitmap is null.");
			return;
		}
		
		if(mBitmapShader != null){
			mBitmapShader = null;
		}
		
		/**
		 * 将mBitmap作为着色器,也就是在指定的区域内绘制mBitmap
		 */
		mBitmapShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
		
		/**
		 * 缩放比例 
		 */
		float scale = 1.0f;
		switch (showType) {
		case TYPE_CIRCLE:
			/**
			 * 拿图片的宽高最小值做缩放比例 
			 */
			scale = mCircleViewWidth * 1.0F / Math.min(mBitmap.getWidth(), mBitmap.getHeight());
			break;
		case TYPE_ROUND:
			/**
			 * 如果图片的宽高与view的宽高不匹配,缩放的宽高一定要大于view的宽高才能填充完整view,所以要取较大值 
			 */
			scale = Math.max(getWidth() * 1.0f /mBitmap.getWidth() , getHeight() * 1.0f / mBitmap.getHeight() );
			break;
		}
		
		/**
		 * 变换矩阵设置缩放大小 
		 */
		mMatrix.setScale(scale,scale);
		
		/**
		 * 设置变换矩阵 
		 */
		mBitmapShader.setLocalMatrix(mMatrix);
		
		/**
		 * 设置着色器 
		 */
		mBitmapPaint.setShader(mBitmapShader);
	}
	
	/**
	 * 从drawable中获取bitmap
	 */
	private Bitmap getBitmapFromDrawable(Drawable drawable){
		if(drawable == null){
			return null;
		}
		if(drawable instanceof BitmapDrawable){
			return ((BitmapDrawable)drawable).getBitmap();
		}
		
		try {
			Bitmap bitmap = null;
			if(drawable instanceof ColorDrawable){
				bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, 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 (OutOfMemoryError e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 根据手机获取合适的像素大小 
	 */
	private int dp2px(){
		return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_CORNER_ANGLE, 
				getResources().getDisplayMetrics());
	}
}


你可能感兴趣的:(圆角,圆形,RoundImageView)