您的位置:首页 > 移动开发 > Android开发

android:圆形、圆角图片

2015-12-11 11:10 387 查看
当我们涉及到头像的时候,一般会用到圆形或者圆角的图片,以下是继承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());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: