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

Android imageView 自定义单个或多个角为圆角及圆形图片工具

2017-06-22 11:41 537 查看
本文是根据鸿阳大神的http://blog.csdn.net/lmj623565791/article/details/24555655这篇文章改写完成的,感谢大神分享!

闲话不多说直接上代码

public class UserDefinedCircleImageView extends ImageView {
/**
* 图片的类型,圆形or圆角
*/
private int type;
private List<Integer> type_round=new ArrayList<>();
//圆形
public static final int TYPE_CIRCLE = 0;
//圆角
public static final int TYPE_ROUND = 1;
//左上为直角
public static final int TOP_LEFT = 2;
//左下为直角
public static final int BOTTOM_LEFT = 3;
//右上为直角
public static final int TOP_RIGHT = 4;
//右下为直角
public static final int BOTTOM_RIGHT = 5;
/**
* 圆角大小的默认值
*/
private static final int BODER_RADIUS_DEFAULT = 10;
/**
* 圆角的大小
*/
private int mBorderRadius;

/**
* 绘图的Paint
*/
private Paint mBitmapPaint;
/**
* 圆角的半径
*/
private int mRadius;
/**
* 3x3 矩阵,主要用于缩小放大
*/
private Matrix mMatrix;
/**
* 渲染图像,使用图像为绘制图形着色
*/
private BitmapShader mBitmapShader;
/**
* view的宽度
*/
private int mWidth;
private RectF mRoundRect;

public UserDefinedCircleImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mMatrix = new Matrix();
mBitmapPaint = new Paint();
mBitmapPaint.setAntiAlias(true);

TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.RoundImageView);

mBorderRadius = a.getDimensionPixelSize(
R.styleable.RoundImageView_borderRadius, (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
BODER_RADIUS_DEFAULT, getResources()
.getDisplayMetrics()));// 默认为10dp
type = a.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);// 默认为Circle

a.recycle();
}

public UserDefinedCircleImageView(Context context) {
this(context, null);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

/**
* 如果类型是圆形,则强制改变view的宽高一致,以小值为准
*/
if (type == TYPE_CIRCLE) {

111b3
mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = mWidth / 2;
setMeasuredDimension(mWidth, mWidth);
}

}

/**
* 初始化BitmapShader
*/
private void setUpShader() {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}

Bitmap bmp = drawableToBitamp(drawable);
// 将bmp作为着色器,就是在指定区域内绘制bmp
mBitmapShader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
float scale = 1.0f;
if (type == TYPE_CIRCLE) {
// 拿到bitmap宽或高的小值
int bSize = Math.min(bmp.getWidth(), bmp.getHeight());
scale = mWidth * 1.0f / bSize;

} else if (type == TYPE_ROUND) {
Log.e("TAG",
"b'w = " + bmp.getWidth() + " , " + "b'h = "
+ bmp.getHeight());
if (!(bmp.getWidth() == getWidth() && bmp.getHeight() == getHeight())) {
// 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;
scale = Math.max(getWidth() * 1.0f / bmp.getWidth(),
getHeight() * 1.0f / bmp.getHeight());
}

}
// shader的变换矩阵,我们这里主要用于放大或者缩小
mMatrix.setScale(scale, scale);
// 设置变换矩阵
mBitmapShader.setLocalMatrix(mMatrix);
// 设置shader
mBitmapPaint.setShader(mBitmapShader);
}

@Override
protected void onDraw(Canvas canvas) {
Log.e("TAG", "onDraw");
if (getDrawable() == null) {
return;
}
setUpShader();

if (type == TYPE_ROUND) {
canvas.drawRoundRect(mRoundRect, mBorderRadius, mBorderRadius,
mBitmapPaint);
//哪个角不是圆角我再用矩形画出来
for (int i = 0; i < type_round.size(); i++) {

//1.把左上角重新绘制成矩形
if (type_round.get(i) == TOP_LEFT) {
canvas.drawRect(0, 0, mBorderRadius, mBorderRadius, mBitmapPaint);
}
//2.把右上角重新绘制成矩形
if (type_round.get(i) == TOP_RIGHT) {
canvas.drawRect(mRoundRect.right - mBorderRadius, 0, mRoundRect.right, mBorderRadius, mBitmapPaint);
}
//3.把左下角重新绘制成矩形
if (type_round.get(i) == BOTTOM_LEFT) {
canvas.drawRect(0, mRoundRect.bottom - mBorderRadius, mBorderRadius, mRoundRect.bottom, mBitmapPaint);
}
//4.把右下角重新绘制成矩形
if (type_round.get(i) == BOTTOM_RIGHT) {
canvas.drawRect(mRoundRect.right - mBorderRadius, mRoundRect.bottom - mBorderRadius, mRoundRect.right, mRoundRect.bottom, mBitmapPaint);
}
}

} else {
canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint);
// drawSomeThing(canvas);
}
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);

// 圆角图片的范围
if (type == TYPE_ROUND)
mRoundRect = new RectF(0, 0, w, h);
}

/**
* drawable转bitmap
*
* @param drawable
* @return
*/
private Bitmap drawableToBitamp(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bd = (BitmapDrawable) drawable;
return bd.getBitmap();
}
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);
return bitmap;
}

private static final String STATE_INSTANCE = "state_instance";
private static final String STATE_TYPE = "state_type";
private static final String STATE_BORDER_RADIUS = "state_border_radius";

@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState());
bundle.putInt(STATE_TYPE, type);
bundle.putInt(STATE_BORDER_RADIUS, mBorderRadius);
return bundle;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
super.onRestoreInstanceState(((Bundle) state)
.getParcelable(STATE_INSTANCE));
this.type = bundle.getInt(STATE_TYPE);
this.mBorderRadius = bundle.getInt(STATE_BORDER_RADIUS);
} else {
super.onRestoreInstanceState(state);
}

}

public void setBorderRadius(int borderRadius) {
int pxVal = dp2px(borderRadius);
if (this.mBorderRadius != pxVal) {
this.mBorderRadius = pxVal;
invalidate();
}
}

/**
* 圆形图片或四个角都为圆角时调用
* @param type
*/
public void setType(int type) {
if (this.type != type) {
this.type = type;
if (this.type != TYPE_ROUND && this.type != TYPE_CIRCLE) {
this.type = TYPE_CIRCLE;
}
requestLayout();
}

}

/**
* 自定义某一个或多个角为圆角时用
* @param type
* @param whereNeedKeepRightAngle 传入需要保持直角的位置
*/
public void setType(int type, int... whereNeedKeepRightAngle) {
for (int item :whereNeedKeepRightAngle){
type_round.add(item);
}
if (this.type != type) {
this.type = type;
if (this.type != TYPE_ROUND && this.type != TYPE_CIRCLE) {
this.type = TYPE_CIRCLE;
}
requestLayout();
}

}

public int dp2px(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getResources().getDisplayMetrics());
}
}

其中用到的

styleable需手动在res文件夹下的values文件夹中新建attr.xml 内容如下

<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="borderRadius" format="dimension" />
<attr name="type">
<enum name="circle" value="0" />
<enum name="round" value="1" />
</attr>
<declare-styleable name="RoundImageView">
<attr name="borderRadius" />
<attr name="type" />
</declare-styleable>
</resources>

 

 

用法很简单

xml布局

<mytenplate.myk.com.myimagetest.UserDefinedCircleImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/image"/>

Java代码

imageView = (UserDefinedCircleImageView)findViewById(R.id.iv);
//设置一个或多个圆角
//UserDefinedCircleImageView.TOP_RIGHT 和 UserDefinedCircleImageView.BOTTOM_LEFT为需要保持直角的
imageView.setType(UserDefinedCircleImageView.TYPE_ROUND,UserDefinedCircleImageView.TOP_RIGHT,UserDefinedCircleImageView.BOTTOM_LEFT);
//设置圆角角度
imageView.setBorderRadius(20);
//圆形图片
//        imageView.setType(UserDefinedCircleImageView.TYPE_CIRCLE);
//四个角都为圆角图片
//        imageView.setType(UserDefinedCircleImageView.TYPE_ROUND);

是不是很方便啊。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐