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

Android 中使用过圆角照片控件

2016-07-02 23:27 429 查看
Android 中使用过圆角照片控件

Android 特别好使的两个圆角照片控件

控件一:

/***
* 圆角照片
* @author madreain
*/
public class CircleImageView extends ImageView {

private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;

private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
private static final int COLORDRAWABLE_DIMENSION = 2;

private static final int DEFAULT_BORDER_WIDTH = 0;
private static final int DEFAULT_BORDER_COLOR = Color.BLACK;

private final RectF mDrawableRect = new RectF();
private final RectF mBorderRect = new RectF();

private final Matrix mShaderMatrix = new Matrix();
private final Paint mBitmapPaint = new Paint();
private final Paint mBorderPaint = new Paint();

private int mBorderColor = DEFAULT_BORDER_COLOR;
private int mBorderWidth = DEFAULT_BORDER_WIDTH;

private Bitmap mBitmap;
private BitmapShader mBitmapShader;
private int mBitmapWidth;
private int mBitmapHeight;

private float mDrawableRadius;
private float mBorderRadius;

private boolean mReady;
private boolean mSetupPending;

public CircleImageView(Context context) {
super(context);

init();
}

public CircleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);

mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);

a.recycle();

init();
}

private void init() {
super.setScaleType(SCALE_TYPE);
mReady = true;

if (mSetupPending) {
setup();
mSetupPending = false;
}
}

@Override
public ScaleType getScaleType() {
return SCALE_TYPE;
}

@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType != SCALE_TYPE) {
throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
}
}

@Override
public void setAdjustViewBounds(boolean adjustViewBounds) {
if (adjustViewBounds) {
throw new IllegalArgumentException("adjustViewBounds not supported.");
}
}

@Override
protected void onDraw(Canvas canvas) {
if (getDrawable() == null) {
return;
}

canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
if (mBorderWidth != 0) {
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
}
}

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

public int getBorderColor() {
return mBorderColor;
}

public void setBorderColor(int borderColor) {
if (borderColor == mBorderColor) {
return;
}

mBorderColor = borderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}

public int getBorderWidth() {
return mBorderWidth;
}

public void setBorderWidth(int borderWidth) {
if (borderWidth == mBorderWidth) {
return;
}

mBorderWidth = borderWidth;
setup();
}

@Override
public void setImageBitmap(Bitmap bm) {
if(getDrawable()!=null){
getDrawable().invalidateSelf();
}
super.setImageBitmap(bm);
mBitmap = bm;
setup();
}

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

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

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

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

if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}

try {
Bitmap bitmap;

if (drawable instanceof ColorDrawable) {
bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
}

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

private void setup() {
if (!mReady) {
mSetupPending = true;
return;
}

if (mBitmap == null) {
return;
}

mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

mBitmapPaint.setAntiAlias(true);
mBitmapPaint.setShader(mBitmapShader);

mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeWidth(mBorderWidth);

mBitmapHeight = mBitmap.getHeight();
mBitmapWidth = mBitmap.getWidth();

mBorderRect.set(0, 0, getWidth(), getHeight());
mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);

mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth);
mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);

updateShaderMatrix();
invalidate();
}

private void updateShaderMatrix() {
float scale;
float dx = 0;
float dy = 0;

mShaderMatrix.set(null);

if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
scale = mDrawableRect.height() / (float) mBitmapHeight;
dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
scale = mDrawableRect.width() / (float) mBitmapWidth;
dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
}

mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth);

mBitmapShader.setLocalMatrix(mShaderMatrix);
}

}


xml布局

<com.motoband.ui.view.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/civ_head_portrait"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
app:border_width="2dip"      //设置圆角照片外层的包裹圈的颜色及宽度
app:border_color="@color/head_portrait_mail_color_male"
android:background="@mipmap/me_headportrait_2"/>


控件二:

/***
* 圆角照片
* @author madreain
*/
public class RoundImageView extends ImageView {

private MaskType mMaskType;
private Path mPath;
private float mRadius;
private float mBorderWidth;
private Paint mBorderPaint;
private int mBorderColor;
private static final int DEFAULT_BORDER_COLOR = Color.WHITE;

private static final MaskType[] sMaskTypeArray = {
MaskType.RECTANGLE,
MaskType.CIRCLE,
MaskType.ROUNDRECTANGLE,
MaskType.ROUNDRECTANGLETOP
};

public RoundImageView(Context context) {
super(context);
initRoundImageView();
}

public RoundImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initRoundImageView();
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.RoundImageView, defStyle, 0);
int index = a.getInt(R.styleable.RoundImageView_maskType, -1);
if (index >= 0) {
setMaskType(sMaskTypeArray[index]);
}

mBorderColor = a.getColor(R.styleable.RoundImageView_borderColor_Ri, Color.BLACK);
mBorderWidth = a.getDimensionPixelSize(R.styleable.RoundImageView_borderWidth_Ri, 0);

a.recycle();
}

private void initRoundImageView() {
mMaskType = MaskType.CIRCLE;
mRadius = 20;
mPath = new Path();
mBorderPaint = new Paint();
mBorderColor = DEFAULT_BORDER_COLOR;
mBorderPaint.setColor(mBorderColor);
}

/**
*
* @MaskType.ROUNDRECTANGLE
* @MaskType.ROUNDRECTANGLETOP
* @param radius
*/
public void setRadius(int radius) {
if (mRadius == radius) {
return;
}

mRadius = radius;
invalidate();
}

public void setBorderColor(@ColorInt int color) {
if (mBorderColor == color) {
return;
}

mBorderColor = color;
mBorderPaint.setColor(color);
invalidate();
}

public void setBorderColorResource(@ColorRes int colorResource) {
setBorderColor(getContext().getResources().getColor(colorResource));
}

public void setBorderWidth(float borderWidth) {
if (mBorderWidth == borderWidth) {
return;
}
mBorderWidth = borderWidth;
invalidate();
}

public void setMaskType(MaskType maskType) {
if (maskType == null) {
throw new NullPointerException();
}

if (mMaskType != maskType) {
mMaskType = maskType;

requestLayout();
invalidate();
}
}

@Override
protected void onDraw(Canvas canvas) {
canvas.save();
drawPath();
canvas.clipPath(mPath);
super.onDraw(canvas);
canvas.restore();
drawCanvas(canvas);

}

private void drawPath() {
int width = getWidth();
int height = getHeight();
switch (mMaskType) {
case RECTANGLE:
mPath.reset();
mPath.addRect(new RectF(mBorderWidth / 2, mBorderWidth / 2, width - mBorderWidth / 2, height - mBorderWidth / 2), Path.Direction.CW);
mPath.close();
break;
case CIRCLE:
float r = Math.min(width, height) / 2;
mPath.reset();
mPath.addCircle(width / 2, height / 2, r, Path.Direction.CW);
mPath.close();
break;
case ROUNDRECTANGLE:
mPath.reset();
mPath.addRoundRect(new RectF(mBorderWidth / 4, mBorderWidth / 4, width - mBorderWidth / 4, height - mBorderWidth / 4), mRadius, mRadius, Path.Direction.CW);
mPath.close();
break;
case ROUNDRECTANGLETOP:
mPath.reset();
mPath.addCircle(mRadius, mRadius, mRadius, Path.Direction.CW);
mPath.addCircle(width - mRadius, mRadius, mRadius, Path.Direction.CW);
mPath.addRect(mRadius, 0, width - mRadius, 2 * mRadius, Path.Direction.CW);
mPath.addRect(0, mRadius, width, height, Path.Direction.CW);
mPath.close();
break;
}
}

private void drawCanvas(Canvas canvas) {
int width = getWidth();
int height = getHeight();
if (mBorderWidth <= 0) {
return;
}
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
switch (mMaskType) {
case RECTANGLE:
canvas.drawRect(new RectF(0, 0, width, height), mBorderPaint);
break;
case CIRCLE:
float r = Math.min(width, height) / 2;
canvas.drawCircle(width / 2, height / 2, r - mBorderWidth / 2, mBorderPaint);
break;
case ROUNDRECTANGLE:
canvas.drawRoundRect(new RectF(0, 0, width, height), mRadius, mRadius,mBorderPaint);
break;
}

}

/**
* options for mask the imageview
*/
public enum MaskType {

/**
* a parallelogram with four right angles
*/
RECTANGLE(0),
/**
*
*/
CIRCLE(1),
/**
*a parallelogram with four circle angles
*/
ROUNDRECTANGLE(2),

/**
* a parallelogram with two top circle angles
*/
ROUNDRECTANGLETOP(3);

final int mNativeInt;

MaskType(int ni) {
mNativeInt = ni;
}
}
}


xml布局使用

<com.motoband.widget.RoundImageView
android:id="@+id/img_set_photo"
android:layout_width="@dimen/dp40"
android:layout_height="@dimen/dp40"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/dp2.5"
android:layout_marginStart="@dimen/dp2.5"
android:layout_marginTop="@dimen/dp2.5"

android:scaleType="centerCrop"
maple:maskType="CIRCLE" />


这不如果需要在圆角照片的外层加一个圆圈的圈,需要另外写一个
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: