在网上找到的一个实现圆角图片的方法,直接上代码,
RoundedDrawable.java
import android.annotation.SuppressLint;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.util.Log;
import android.widget.ImageView.ScaleType;
@SuppressWarnings("UnusedDeclaration")
public class RoundedDrawable extends Drawable {
public static final String TAG = "RoundedDrawable";
public static final int DEFAULT_BORDER_COLOR = Color.BLACK;
private final RectF mBounds = new RectF();
private final RectF mDrawableRect = new RectF();
private final RectF mBitmapRect = new RectF();
private final Bitmap mBitmap;
private final Paint mBitmapPaint;
private final int mBitmapWidth;
private final int mBitmapHeight;
private final RectF mBorderRect = new RectF();
private final Paint mBorderPaint;
private final Matrix mShaderMatrix = new Matrix();
private BitmapShader mBitmapShader;
private Shader.TileMode mTileModeX = Shader.TileMode.CLAMP;
private Shader.TileMode mTileModeY = Shader.TileMode.CLAMP;
private boolean mRebuildShader = true;
private float mCornerRadius = 0;
private boolean mOval = false;
private float mBorderWidth = 0;
private ColorStateList mBorderColor = ColorStateList
.valueOf(DEFAULT_BORDER_COLOR);
private ScaleType mScaleType = ScaleType.FIT_CENTER;
public RoundedDrawable(Bitmap bitmap) {
mBitmap = bitmap;
mBitmapWidth = bitmap.getWidth();
mBitmapHeight = bitmap.getHeight();
mBitmapRect.set(0, 0, mBitmapWidth, mBitmapHeight);
mBitmapPaint = new Paint();
mBitmapPaint.setStyle(Paint.Style.FILL);
mBitmapPaint.setAntiAlias(true);
mBorderPaint = new Paint();
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor.getColorForState(getState(),
DEFAULT_BORDER_COLOR));
mBorderPaint.setStrokeWidth(mBorderWidth);
}
public static RoundedDrawable fromBitmap(Bitmap bitmap) {
if (bitmap != null) {
return new RoundedDrawable(bitmap);
} else {
return null;
}
}
public static Drawable fromDrawable(Drawable drawable) {
if (drawable != null) {
if (drawable instanceof RoundedDrawable) {
// just return if it's already a RoundedDrawable
return drawable;
} else if (drawable instanceof LayerDrawable) {
LayerDrawable ld = (LayerDrawable) drawable;
int num = ld.getNumberOfLayers();
// loop through layers to and change to RoundedDrawables if
// possible
for (int i = 0; i < num; i++) {
Drawable d = ld.getDrawable(i);
ld.setDrawableByLayerId(ld.getId(i), fromDrawable(d));
}
return ld;
}
// try to get a bitmap from the drawable and
Bitmap bm = drawableToBitmap(drawable);
if (bm != null) {
return new RoundedDrawable(bm);
}
}
return drawable;
}
public static Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap;
int width = Math.max(drawable.getIntrinsicWidth(), 2);
int height = Math.max(drawable.getIntrinsicHeight(), 2);
try {
bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
} catch (Exception e) {
e.printStackTrace();
Log.w(TAG, "Failed to create bitmap from drawable!");
bitmap = null;
}
return bitmap;
}
@Override
public boolean isStateful() {
return mBorderColor.isStateful();
}
@Override
protected boolean onStateChange(int[] state) {
int newColor = mBorderColor.getColorForState(state, 0);
if (mBorderPaint.getColor() != newColor) {
mBorderPaint.setColor(newColor);
return true;
} else {
return super.onStateChange(state);
}
}
private void updateShaderMatrix() {
float scale;
float dx;
float dy;
switch (mScaleType) {
case CENTER:
mBorderRect.set(mBounds);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.reset();
mShaderMatrix
.setTranslate(
(int) ((mBorderRect.width() - mBitmapWidth) * 0.5f + 0.5f),
(int) ((mBorderRect.height() - mBitmapHeight) * 0.5f + 0.5f));
break;
case CENTER_CROP:
mBorderRect.set(mBounds);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.reset();
dx = 0;
dy = 0;
if (mBitmapWidth * mBorderRect.height() > mBorderRect.width()
* mBitmapHeight) {
scale = mBorderRect.height() / (float) mBitmapHeight;
dx = (mBorderRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
scale = mBorderRect.width() / (float) mBitmapWidth;
dy = (mBorderRect.height() - mBitmapHeight * scale) * 0.5f;
}
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth,
(int) (dy + 0.5f) + mBorderWidth);
break;
case CENTER_INSIDE:
mShaderMatrix.reset();
if (mBitmapWidth <= mBounds.width()
&& mBitmapHeight <= mBounds.height()) {
scale = 1.0f;
} else {
scale = Math.min(mBounds.width() / (float) mBitmapWidth,
mBounds.height() / (float) mBitmapHeight);
}
dx = (int) ((mBounds.width() - mBitmapWidth * scale) * 0.5f + 0.5f);
dy = (int) ((mBounds.height() - mBitmapHeight * scale) * 0.5f + 0.5f);
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate(dx, dy);
mBorderRect.set(mBitmapRect);
mShaderMatrix.mapRect(mBorderRect);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect,
Matrix.ScaleToFit.FILL);
break;
default:
case FIT_CENTER:
mBorderRect.set(mBitmapRect);
mShaderMatrix.setRectToRect(mBitmapRect, mBounds,
Matrix.ScaleToFit.CENTER);
mShaderMatrix.mapRect(mBorderRect);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect,
Matrix.ScaleToFit.FILL);
break;
case FIT_END:
mBorderRect.set(mBitmapRect);
mShaderMatrix.setRectToRect(mBitmapRect, mBounds,
Matrix.ScaleToFit.END);
mShaderMatrix.mapRect(mBorderRect);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect,
Matrix.ScaleToFit.FILL);
break;
case FIT_START:
mBorderRect.set(mBitmapRect);
mShaderMatrix.setRectToRect(mBitmapRect, mBounds,
Matrix.ScaleToFit.START);
mShaderMatrix.mapRect(mBorderRect);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect,
Matrix.ScaleToFit.FILL);
break;
case FIT_XY:
mBorderRect.set(mBounds);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.reset();
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect,
Matrix.ScaleToFit.FILL);
break;
}
mDrawableRect.set(mBorderRect);
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mBounds.set(bounds);
updateShaderMatrix();
}
@Override
public void draw(Canvas canvas) {
if (mRebuildShader) {
mBitmapShader = new BitmapShader(mBitmap, mTileModeX, mTileModeY);
if (mTileModeX == Shader.TileMode.CLAMP
&& mTileModeY == Shader.TileMode.CLAMP) {
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
mBitmapPaint.setShader(mBitmapShader);
mRebuildShader = false;
}
if (mOval) {
if (mBorderWidth > 0) {
canvas.drawOval(mDrawableRect, mBitmapPaint);
canvas.drawOval(mBorderRect, mBorderPaint);
} else {
canvas.drawOval(mDrawableRect, mBitmapPaint);
}
} else {
if (mBorderWidth > 0) {
canvas.drawRoundRect(mDrawableRect, Math.max(mCornerRadius, 0),
Math.max(mCornerRadius, 0), mBitmapPaint);
canvas.drawRoundRect(mBorderRect, mCornerRadius, mCornerRadius,
mBorderPaint);
} else {
canvas.drawRoundRect(mDrawableRect, mCornerRadius,
mCornerRadius, mBitmapPaint);
}
}
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@SuppressLint("Override")
public int getAlpha() {
return mBitmapPaint.getAlpha();
}
@Override
public void setAlpha(int alpha) {
mBitmapPaint.setAlpha(alpha);
invalidateSelf();
}
// @Override
public ColorFilter getColorFilter() {
return mBitmapPaint.getColorFilter();
}
@Override
public void setColorFilter(ColorFilter cf) {
mBitmapPaint.setColorFilter(cf);
invalidateSelf();
}
@Override
public void setDither(boolean dither) {
mBitmapPaint.setDither(dither);
invalidateSelf();
}
@Override
public void setFilterBitmap(boolean filter) {
mBitmapPaint.setFilterBitmap(filter);
invalidateSelf();
}
@Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}
@Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}
public float getCornerRadius() {
return mCornerRadius;
}
public RoundedDrawable setCornerRadius(float radius) {
mCornerRadius = radius;
return this;
}
public float getBorderWidth() {
return mBorderWidth;
}
public RoundedDrawable setBorderWidth(float width) {
mBorderWidth = width;
mBorderPaint.setStrokeWidth(mBorderWidth);
return this;
}
public int getBorderColor() {
return mBorderColor.getDefaultColor();
}
public RoundedDrawable setBorderColor(int color) {
return setBorderColor(ColorStateList.valueOf(color));
}
public ColorStateList getBorderColors() {
return mBorderColor;
}
public RoundedDrawable setBorderColor(ColorStateList colors) {
mBorderColor = colors != null ? colors : ColorStateList.valueOf(0);
mBorderPaint.setColor(mBorderColor.getColorForState(getState(),
DEFAULT_BORDER_COLOR));
return this;
}
public boolean isOval() {
return mOval;
}
public RoundedDrawable setOval(boolean oval) {
mOval = oval;
return this;
}
public ScaleType getScaleType() {
return mScaleType;
}
public RoundedDrawable setScaleType(ScaleType scaleType) {
if (scaleType == null) {
scaleType = ScaleType.FIT_CENTER;
}
if (mScaleType != scaleType) {
mScaleType = scaleType;
updateShaderMatrix();
}
return this;
}
public Shader.TileMode getTileModeX() {
return mTileModeX;
}
public RoundedDrawable setTileModeX(Shader.TileMode tileModeX) {
if (mTileModeX != tileModeX) {
mTileModeX = tileModeX;
mRebuildShader = true;
invalidateSelf();
}
return this;
}
public Shader.TileMode getTileModeY() {
return mTileModeY;
}
public RoundedDrawable setTileModeY(Shader.TileMode tileModeY) {
if (mTileModeY != tileModeY) {
mTileModeY = tileModeY;
mRebuildShader = true;
invalidateSelf();
}
return this;
}
public Bitmap toBitmap() {
return drawableToBitmap(this);
}
}
RoundedTransformationBuilder.java
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.animation.Transformation;
import android.widget.ImageView;
public final class RoundedTransformationBuilder {
// private final Resources mResources;
private final DisplayMetrics mDisplayMetrics;
private float mCornerRadius = 0;
private boolean mOval = false;
private float mBorderWidth = 0;
private ColorStateList mBorderColor = ColorStateList
.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
private ImageView.ScaleType mScaleType = ImageView.ScaleType.FIT_CENTER;
public RoundedTransformationBuilder() {
mDisplayMetrics = Resources.getSystem().getDisplayMetrics();
}
public RoundedTransformationBuilder scaleType(ImageView.ScaleType scaleType) {
mScaleType = scaleType;
return this;
}
/**
* set corner radius in px
*/
public RoundedTransformationBuilder cornerRadius(float radiusPx) {
mCornerRadius = radiusPx;
return this;
}
/**
* set corner radius in dip
*/
public RoundedTransformationBuilder cornerRadiusDp(float radiusDp) {
mCornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
radiusDp, mDisplayMetrics);
return this;
}
/**
* set border width in px
*/
public RoundedTransformationBuilder borderWidth(float widthPx) {
mBorderWidth = widthPx;
return this;
}
/**
* set border width in dip
*/
public RoundedTransformationBuilder borderWidthDp(float widthDp) {
mBorderWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
widthDp, mDisplayMetrics);
return this;
}
/**
* set border color
*/
public RoundedTransformationBuilder borderColor(int color) {
mBorderColor = ColorStateList.valueOf(color);
return this;
}
public RoundedTransformationBuilder borderColor(ColorStateList colors) {
mBorderColor = colors;
return this;
}
public RoundedTransformationBuilder oval(boolean oval) {
mOval = oval;
return this;
}
public Transformation build() {
return new Transformation() {
public Bitmap transform(Bitmap source) {
Bitmap transformed = RoundedDrawable.fromBitmap(source)
.setScaleType(mScaleType)
.setCornerRadius(mCornerRadius)
.setBorderWidth(mBorderWidth)
.setBorderColor(mBorderColor).setOval(mOval).toBitmap();
if (!source.equals(transformed)) {
source.recycle();
}
return transformed;
}
public String key() {
return "r:" + mCornerRadius + "b:" + mBorderWidth + "c:"
+ mBorderColor + "o:" + mOval;
}
};
}
}
import com.siso.beautymirror.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.ColorFilter;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
@SuppressWarnings("UnusedDeclaration")
public class RoundedImageView extends ImageView {
// Constants for tile mode attributes
private static final int TILE_MODE_UNDEFINED = -2;
private static final int TILE_MODE_CLAMP = 0;
private static final int TILE_MODE_REPEAT = 1;
private static final int TILE_MODE_MIRROR = 2;
public static final String TAG = "RoundedImageView";
public static final float DEFAULT_RADIUS = 0f;
public static final float DEFAULT_BORDER_WIDTH = 0f;
public static final Shader.TileMode DEFAULT_TILE_MODE = Shader.TileMode.CLAMP;
private static final ScaleType[] SCALE_TYPES = {
ScaleType.MATRIX,
ScaleType.FIT_XY,
ScaleType.FIT_START,
ScaleType.FIT_CENTER,
ScaleType.FIT_END,
ScaleType.CENTER,
ScaleType.CENTER_CROP,
ScaleType.CENTER_INSIDE
};
private float cornerRadius = DEFAULT_RADIUS;
private float borderWidth = DEFAULT_BORDER_WIDTH;
private ColorStateList borderColor =
ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
private boolean isOval = false;
private boolean mutateBackground = false;
private Shader.TileMode tileModeX = DEFAULT_TILE_MODE;
private Shader.TileMode tileModeY = DEFAULT_TILE_MODE;
private ColorFilter mColorFilter = null;
private boolean mHasColorFilter = false;
private boolean mColorMod = false;
private int mResource;
private Drawable mDrawable;
private Drawable mBackgroundDrawable;
private ScaleType mScaleType;
public RoundedImageView(Context context) {
super(context);
}
public RoundedImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageView, defStyle, 0);
int index = a.getInt(R.styleable.RoundedImageView_android_scaleType, -1);
if (index >= 0) {
setScaleType(SCALE_TYPES[index]);
} else {
// default scaletype to FIT_CENTER
setScaleType(ScaleType.FIT_CENTER);
}
cornerRadius = a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius, -1);
borderWidth = a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_border_width, -1);
// don't allow negative values for radius and border
if (cornerRadius < 0) {
cornerRadius = DEFAULT_RADIUS;
}
if (borderWidth < 0) {
borderWidth = DEFAULT_BORDER_WIDTH;
}
borderColor = a.getColorStateList(R.styleable.RoundedImageView_riv_border_color);
if (borderColor == null) {
borderColor = ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
}
mutateBackground = a.getBoolean(R.styleable.RoundedImageView_riv_mutate_background, false);
isOval = a.getBoolean(R.styleable.RoundedImageView_riv_oval, false);
final int tileMode = a.getInt(R.styleable.RoundedImageView_riv_tile_mode, TILE_MODE_UNDEFINED);
if (tileMode != TILE_MODE_UNDEFINED) {
setTileModeX(parseTileMode(tileMode));
setTileModeY(parseTileMode(tileMode));
}
final int tileModeX = a.getInt(R.styleable.RoundedImageView_riv_tile_mode_x, TILE_MODE_UNDEFINED);
if (tileModeX != TILE_MODE_UNDEFINED) {
setTileModeX(parseTileMode(tileModeX));
}
final int tileModeY = a.getInt(R.styleable.RoundedImageView_riv_tile_mode_y, TILE_MODE_UNDEFINED);
if (tileModeY != TILE_MODE_UNDEFINED) {
setTileModeY(parseTileMode(tileModeY));
}
updateDrawableAttrs();
updateBackgroundDrawableAttrs(true);
a.recycle();
}
private static Shader.TileMode parseTileMode(int tileMode) {
switch (tileMode) {
case TILE_MODE_CLAMP:
return Shader.TileMode.CLAMP;
case TILE_MODE_REPEAT:
return Shader.TileMode.REPEAT;
case TILE_MODE_MIRROR:
return Shader.TileMode.MIRROR;
default:
return null;
}
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
invalidate();
}
/**
* Return the current scale type in use by this ImageView.
*
* @attr ref android.R.styleable#ImageView_scaleType
* @see android.widget.ImageView.ScaleType
*/
@Override
public ScaleType getScaleType() {
return mScaleType;
}
/**
* Controls how the image should be resized or moved to match the size
* of this ImageView.
*
* @param scaleType The desired scaling mode.
* @attr ref android.R.styleable#ImageView_scaleType
*/
@Override
public void setScaleType(ScaleType scaleType) {
assert scaleType != null;
if (mScaleType != scaleType) {
mScaleType = scaleType;
switch (scaleType) {
case CENTER:
case CENTER_CROP:
case CENTER_INSIDE:
case FIT_CENTER:
case FIT_START:
case FIT_END:
case FIT_XY:
super.setScaleType(ScaleType.FIT_XY);
break;
default:
super.setScaleType(scaleType);
break;
}
updateDrawableAttrs();
updateBackgroundDrawableAttrs(false);
invalidate();
}
}
@Override
public void setImageDrawable(Drawable drawable) {
mResource = 0;
mDrawable = RoundedDrawable.fromDrawable(drawable);
updateDrawableAttrs();
super.setImageDrawable(mDrawable);
}
@Override
public void setImageBitmap(Bitmap bm) {
mResource = 0;
mDrawable = RoundedDrawable.fromBitmap(bm);
updateDrawableAttrs();
super.setImageDrawable(mDrawable);
}
@Override
public void setImageResource(int resId) {
if (mResource != resId) {
mResource = resId;
mDrawable = resolveResource();
updateDrawableAttrs();
super.setImageDrawable(mDrawable);
}
}
@Override public void setImageURI(Uri uri) {
super.setImageURI(uri);
setImageDrawable(getDrawable());
}
private Drawable resolveResource() {
Resources rsrc = getResources();
if (rsrc == null) { return null; }
Drawable d = null;
if (mResource != 0) {
try {
d = rsrc.getDrawable(mResource);
} catch (Exception e) {
Log.w(TAG, "Unable to find resource: " + mResource, e);
// Don't try again.
mResource = 0;
}
}
return RoundedDrawable.fromDrawable(d);
}
@SuppressLint("Override")
public void setBackground(Drawable background) {
setBackgroundDrawable(background);
}
private void updateDrawableAttrs() {
updateAttrs(mDrawable);
}
private void updateBackgroundDrawableAttrs(boolean convert) {
if (mutateBackground) {
if (convert) {
mBackgroundDrawable = RoundedDrawable.fromDrawable(mBackgroundDrawable);
}
updateAttrs(mBackgroundDrawable);
}
}
@Override public void setColorFilter(ColorFilter cf) {
if (mColorFilter != cf) {
mColorFilter = cf;
mHasColorFilter = true;
mColorMod = true;
applyColorMod();
invalidate();
}
}
private void applyColorMod() {
// Only mutate and apply when modifications have occurred. This should
// not reset the mColorMod flag, since these filters need to be
// re-applied if the Drawable is changed.
if (mDrawable != null && mColorMod) {
mDrawable = mDrawable.mutate();
if (mHasColorFilter) {
mDrawable.setColorFilter(mColorFilter);
}
// TODO: support, eventually...
//mDrawable.setXfermode(mXfermode);
//mDrawable.setAlpha(mAlpha * mViewAlphaScale >> 8);
}
}
private void updateAttrs(Drawable drawable) {
if (drawable == null) { return; }
if (drawable instanceof RoundedDrawable) {
((RoundedDrawable) drawable)
.setScaleType(mScaleType)
.setCornerRadius(cornerRadius)
.setBorderWidth(borderWidth)
.setBorderColor(borderColor)
.setOval(isOval)
.setTileModeX(tileModeX)
.setTileModeY(tileModeY);
applyColorMod();
} else if (drawable instanceof LayerDrawable) {
// loop through layers to and set drawable attrs
LayerDrawable ld = ((LayerDrawable) drawable);
for (int i = 0, layers = ld.getNumberOfLayers(); i < layers; i++) {
updateAttrs(ld.getDrawable(i));
}
}
}
@Override
@Deprecated
public void setBackgroundDrawable(Drawable background) {
mBackgroundDrawable = background;
updateBackgroundDrawableAttrs(true);
super.setBackgroundDrawable(mBackgroundDrawable);
}
public float getCornerRadius() {
return cornerRadius;
}
public void setCornerRadiusDimen(int resId) {
setCornerRadius(getResources().getDimension(resId));
}
public void setCornerRadius(float radius) {
if (cornerRadius == radius) { return; }
cornerRadius = radius;
updateDrawableAttrs();
updateBackgroundDrawableAttrs(false);
}
public float getBorderWidth() {
return borderWidth;
}
public void setBorderWidth(int resId) {
setBorderWidth(getResources().getDimension(resId));
}
public void setBorderWidth(float width) {
if (borderWidth == width) { return; }
borderWidth = width;
updateDrawableAttrs();
updateBackgroundDrawableAttrs(false);
invalidate();
}
public int getBorderColor() {
return borderColor.getDefaultColor();
}
public void setBorderColor(int color) {
setBorderColor(ColorStateList.valueOf(color));
}
public ColorStateList getBorderColors() {
return borderColor;
}
public void setBorderColor(ColorStateList colors) {
if (borderColor.equals(colors)) { return; }
borderColor =
(colors != null) ? colors : ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
updateDrawableAttrs();
updateBackgroundDrawableAttrs(false);
if (borderWidth > 0) {
invalidate();
}
}
public boolean isOval() {
return isOval;
}
public void setOval(boolean oval) {
isOval = oval;
updateDrawableAttrs();
updateBackgroundDrawableAttrs(false);
invalidate();
}
public Shader.TileMode getTileModeX() {
return tileModeX;
}
public void setTileModeX(Shader.TileMode tileModeX) {
if (this.tileModeX == tileModeX) { return; }
this.tileModeX = tileModeX;
updateDrawableAttrs();
updateBackgroundDrawableAttrs(false);
invalidate();
}
public Shader.TileMode getTileModeY() {
return tileModeY;
}
public void setTileModeY(Shader.TileMode tileModeY) {
if (this.tileModeY == tileModeY) { return; }
this.tileModeY = tileModeY;
updateDrawableAttrs();
updateBackgroundDrawableAttrs(false);
invalidate();
}
public boolean mutatesBackground() {
return mutateBackground;
}
public void mutateBackground(boolean mutate) {
if (mutateBackground == mutate) { return; }
mutateBackground = mutate;
updateBackgroundDrawableAttrs(true);
invalidate();
}
}
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RoundedImageView">
<attr name="riv_corner_radius" format="dimension" />
<attr name="riv_border_width" format="dimension" />
<attr name="riv_border_color" format="color" />
<attr name="riv_mutate_background" format="boolean" />
<attr name="riv_oval" format="boolean" />
<attr name="android:scaleType" />
<attr name="riv_tile_mode">
<enum name="clamp" value="0" />
<enum name="repeat" value="1" />
<enum name="mirror" value="2" />
</attr>
<attr name="riv_tile_mode_x">
<enum name="clamp" value="0" />
<enum name="repeat" value="1" />
<enum name="mirror" value="2" />
</attr>
<attr name="riv_tile_mode_y">
<enum name="clamp" value="0" />
<enum name="repeat" value="1" />
<enum name="mirror" value="2" />
</attr>
</declare-styleable>
</resources>
用法
<com.siso.beautymirror.view.RoundedImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/adapter_cart_image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="4"
android:scaleType="centerCrop"
android:src="@drawable/aa"
app:riv_border_color="@color/transparent" 边框颜色
app:riv_border_width="1px"
app:riv_corner_radius="@dimen/app_twelve" 圆形角度
app:riv_mutate_background="true"
app:riv_oval="false"
app:riv_tile_mode="repeat" />