我使用此link
使用了Rounded Imageview组件现在我想要的是,我想在这个功能中设置图像比例类型。我试过了center,centercrop,fitxy等。但是没有根据比例类型进行裁剪或设置。
请告诉我怎么做。
答案 0 :(得分:0)
来自this link的代码可能更好吗?
据我所知,它在内存使用方面甚至更好。
这是代码:
RoundedImageView.java
public class RoundedImageView extends ImageView {
// based on https://github.com/makeramen/RoundedImageView
public static final String TAG = "RoundedImageView";
public static final int DEFAULT_RADIUS = 0;
public static final int DEFAULT_BORDER = 0;
public static final int DEFAULT_BORDER_COLOR = Color.BLACK;
private int mCornerRadius;
private int mBorderWidth;
private int mBorderColor;
private boolean roundBackground;
private Drawable mDrawable;
private Drawable mBackgroundDrawable;
private ScaleType mScaleType;
private static final ScaleType[] sScaleTypeArray = { ScaleType.MATRIX, ScaleType.FIT_XY, ScaleType.FIT_START,
ScaleType.FIT_CENTER, ScaleType.FIT_END, ScaleType.CENTER, ScaleType.CENTER_CROP, ScaleType.CENTER_INSIDE };
public RoundedImageView(final Context context) {
super(context);
mCornerRadius = DEFAULT_RADIUS;
mBorderWidth = DEFAULT_BORDER;
mBorderColor = DEFAULT_BORDER_COLOR;
}
public RoundedImageView(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundedImageView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageView, defStyle, 0);
final int index = a.getInt(R.styleable.RoundedImageView_android_scaleType, -1);
if (index >= 0) {
setScaleType(sScaleTypeArray[index]);
}
mCornerRadius = a.getDimensionPixelSize(R.styleable.RoundedImageView_corner_radius, -1);
mBorderWidth = a.getDimensionPixelSize(R.styleable.RoundedImageView_border_width, -1);
// don't allow negative values for radius and border
if (mCornerRadius < 0) {
mCornerRadius = DEFAULT_RADIUS;
}
if (mBorderWidth < 0) {
mBorderWidth = DEFAULT_BORDER;
}
mBorderColor = a.getColor(R.styleable.RoundedImageView_border_color, DEFAULT_BORDER_COLOR);
roundBackground = a.getBoolean(R.styleable.RoundedImageView_round_background, false);
a.recycle();
}
/**
* 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(final ScaleType scaleType) {
if (scaleType == null) {
throw new NullPointerException();
}
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;
}
if (mDrawable instanceof RoundedDrawable && ((RoundedDrawable) mDrawable).getScaleType() != scaleType) {
((RoundedDrawable) mDrawable).setScaleType(scaleType);
}
if (mBackgroundDrawable instanceof RoundedDrawable
&& ((RoundedDrawable) mBackgroundDrawable).getScaleType() != scaleType) {
((RoundedDrawable) mBackgroundDrawable).setScaleType(scaleType);
}
setWillNotCacheDrawing(true);
requestLayout();
invalidate();
}
}
/**
* Return the current scale type in use by this ImageView.
*
* @see ImageView.ScaleType
*
* @attr ref android.R.styleable#ImageView_scaleType
*/
@Override
public ScaleType getScaleType() {
return mScaleType;
}
@Override
public void setImageDrawable(final Drawable drawable) {
if (drawable != null) {
mDrawable = RoundedDrawable.fromDrawable(drawable, mCornerRadius, mBorderWidth, mBorderColor);
((RoundedDrawable) mDrawable).setScaleType(mScaleType);
((RoundedDrawable) mDrawable).setCornerRadius(mCornerRadius);
((RoundedDrawable) mDrawable).setBorderWidth(mBorderWidth);
((RoundedDrawable) mDrawable).setBorderColor(mBorderColor);
} else {
mDrawable = null;
}
super.setImageDrawable(mDrawable);
}
@Override
public void setImageBitmap(final Bitmap bm) {
if (bm != null) {
mDrawable = new RoundedDrawable(bm, mCornerRadius, mBorderWidth, mBorderColor);
((RoundedDrawable) mDrawable).setScaleType(mScaleType);
((RoundedDrawable) mDrawable).setCornerRadius(mCornerRadius);
((RoundedDrawable) mDrawable).setBorderWidth(mBorderWidth);
((RoundedDrawable) mDrawable).setBorderColor(mBorderColor);
} else {
mDrawable = null;
}
super.setImageDrawable(mDrawable);
}
// @Override
// public void setBackground(final Drawable background) {
// setBackgroundDrawable(background);
// }
@Override
@Deprecated
public void setBackgroundDrawable(final Drawable background) {
if (roundBackground && background != null) {
mBackgroundDrawable = RoundedDrawable.fromDrawable(background, mCornerRadius, mBorderWidth, mBorderColor);
((RoundedDrawable) mBackgroundDrawable).setScaleType(mScaleType);
((RoundedDrawable) mBackgroundDrawable).setCornerRadius(mCornerRadius);
((RoundedDrawable) mBackgroundDrawable).setBorderWidth(mBorderWidth);
((RoundedDrawable) mBackgroundDrawable).setBorderColor(mBorderColor);
} else {
mBackgroundDrawable = background;
}
super.setBackgroundDrawable(mBackgroundDrawable);
}
public int getCornerRadius() {
return mCornerRadius;
}
public int getBorder() {
return mBorderWidth;
}
public int getBorderColor() {
return mBorderColor;
}
public void setCornerRadius(final int radius) {
if (mCornerRadius == radius) {
return;
}
this.mCornerRadius = radius;
if (mDrawable instanceof RoundedDrawable) {
((RoundedDrawable) mDrawable).setCornerRadius(radius);
}
if (roundBackground && mBackgroundDrawable instanceof RoundedDrawable) {
((RoundedDrawable) mBackgroundDrawable).setCornerRadius(radius);
}
}
public void setBorderWidth(final int width) {
if (mBorderWidth == width) {
return;
}
this.mBorderWidth = width;
if (mDrawable instanceof RoundedDrawable) {
((RoundedDrawable) mDrawable).setBorderWidth(width);
}
if (roundBackground && mBackgroundDrawable instanceof RoundedDrawable) {
((RoundedDrawable) mBackgroundDrawable).setBorderWidth(width);
}
invalidate();
}
public void setBorderColor(final int color) {
if (mBorderColor == color) {
return;
}
this.mBorderColor = color;
if (mDrawable instanceof RoundedDrawable) {
((RoundedDrawable) mDrawable).setBorderColor(color);
}
if (roundBackground && mBackgroundDrawable instanceof RoundedDrawable) {
((RoundedDrawable) mBackgroundDrawable).setBorderColor(color);
}
if (mBorderWidth > 0) {
invalidate();
}
}
public boolean isRoundBackground() {
return roundBackground;
}
public void setRoundBackground(final boolean roundBackground) {
if (this.roundBackground == roundBackground) {
return;
}
this.roundBackground = roundBackground;
if (roundBackground) {
if (mBackgroundDrawable instanceof RoundedDrawable) {
((RoundedDrawable) mBackgroundDrawable).setScaleType(mScaleType);
((RoundedDrawable) mBackgroundDrawable).setCornerRadius(mCornerRadius);
((RoundedDrawable) mBackgroundDrawable).setBorderWidth(mBorderWidth);
((RoundedDrawable) mBackgroundDrawable).setBorderColor(mBorderColor);
} else {
setBackgroundDrawable(mBackgroundDrawable);
}
} else if (mBackgroundDrawable instanceof RoundedDrawable) {
((RoundedDrawable) mBackgroundDrawable).setBorderWidth(0);
((RoundedDrawable) mBackgroundDrawable).setCornerRadius(0);
}
invalidate();
}
}
<强> RoundedDrawable.java 强>
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 BitmapShader mBitmapShader;
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 float mCornerRadius = 0;
private boolean mOval = false;
private float mBorderWidth = 0;
private ColorStateList mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR);
private ScaleType mScaleType = ScaleType.FIT_XY;
public RoundedDrawable(final Bitmap bitmap) {
mBitmapWidth = bitmap.getWidth();
mBitmapHeight = bitmap.getHeight();
mBitmapRect.set(0, 0, mBitmapWidth, mBitmapHeight);
mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapShader.setLocalMatrix(mShaderMatrix);
mBitmapPaint = new Paint();
mBitmapPaint.setStyle(Paint.Style.FILL);
mBitmapPaint.setAntiAlias(true);
mBitmapPaint.setShader(mBitmapShader);
mBorderPaint = new Paint();
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR));
mBorderPaint.setStrokeWidth(mBorderWidth);
}
public static Bitmap drawableToBitmap(final Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap;
final int width = drawable.getIntrinsicWidth();
final int height = drawable.getIntrinsicHeight();
if (width > 0 && height > 0) {
bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
} else {
bitmap = null;
}
return bitmap;
}
public static Drawable fromDrawable(final Drawable drawable) {
if (drawable != null) {
if (drawable instanceof RoundedDrawable) {
// just return if it's already a RoundedDrawable
return drawable;
} else if (drawable instanceof ColorDrawable) {
// FIXME we don't support ColorDrawables yet
return drawable;
} else if (drawable instanceof LayerDrawable) {
final LayerDrawable ld = (LayerDrawable) drawable;
final int num = ld.getNumberOfLayers();
// loop through layers to and change to RoundedDrawables if possible
for (int i = 0; i < num; i++) {
final Drawable d = ld.getDrawable(i);
ld.setDrawableByLayerId(ld.getId(i), fromDrawable(d));
}
return ld;
}
// try to get a bitmap from the drawable and
final Bitmap bm = drawableToBitmap(drawable);
if (bm != null) {
return new RoundedDrawable(bm);
} else {
Log.w(TAG, "Failed to create bitmap from drawable!");
}
}
return drawable;
}
@Override
public boolean isStateful() {
return mBorderColor.isStateful();
}
@Override
protected boolean onStateChange(final int[] state) {
final int newColor = mBorderColor.getColorForState(state, 0);
if (mBorderPaint.getColor() != newColor) {
mBorderPaint.setColor(newColor);
return true;
} else {
return super.onStateChange(state);
}
}
private void updateShaderMatrix() {
mBorderRect.set(mBounds);
mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height()
- mBorderWidth);
float scale;
float dx;
float dy;
switch (mScaleType) {
case CENTER:
mBorderRect.set(mBounds);
mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height()
- mBorderWidth);
mShaderMatrix.set(null);
mShaderMatrix.setTranslate((int) ((mDrawableRect.width() - mBitmapWidth) * 0.5f + 0.5f),
(int) ((mDrawableRect.height() - mBitmapHeight) * 0.5f + 0.5f));
break;
case CENTER_CROP:
mBorderRect.set(mBounds);
mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height()
- mBorderWidth);
mShaderMatrix.set(null);
dx = 0;
dy = 0;
if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
scale = mDrawableRect.height() / mBitmapHeight;
dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
scale = mDrawableRect.width() / mBitmapWidth;
dy = (mDrawableRect.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.set(null);
if (mBitmapWidth <= mBounds.width() && mBitmapHeight <= mBounds.height()) {
scale = 1.0f;
} else {
scale = Math.min(mBounds.width() / mBitmapWidth, mBounds.height() / 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);
mDrawableRect.set(mBorderRect.left + mBorderWidth, mBorderRect.top + mBorderWidth, mBorderRect.right
- mBorderWidth, mBorderRect.bottom - mBorderWidth);
mShaderMatrix.setRectToRect(mBitmapRect, mDrawableRect, Matrix.ScaleToFit.FILL);
break;
case FIT_CENTER:
mBorderRect.set(mBitmapRect);
mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.CENTER);
mShaderMatrix.mapRect(mBorderRect);
mDrawableRect.set(mBorderRect.left + mBorderWidth, mBorderRect.top + mBorderWidth, mBorderRect.right
- mBorderWidth, mBorderRect.bottom - mBorderWidth);
mShaderMatrix.setRectToRect(mBitmapRect, mDrawableRect, Matrix.ScaleToFit.FILL);
break;
case FIT_END:
mBorderRect.set(mBitmapRect);
mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.END);
mShaderMatrix.mapRect(mBorderRect);
mDrawableRect.set(mBorderRect.left + mBorderWidth, mBorderRect.top + mBorderWidth, mBorderRect.right
- mBorderWidth, mBorderRect.bottom - mBorderWidth);
mShaderMatrix.setRectToRect(mBitmapRect, mDrawableRect, Matrix.ScaleToFit.FILL);
break;
case FIT_START:
mBorderRect.set(mBitmapRect);
mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.START);
mShaderMatrix.mapRect(mBorderRect);
mDrawableRect.set(mBorderRect.left + mBorderWidth, mBorderRect.top + mBorderWidth, mBorderRect.right
- mBorderWidth, mBorderRect.bottom - mBorderWidth);
mShaderMatrix.setRectToRect(mBitmapRect, mDrawableRect, Matrix.ScaleToFit.FILL);
break;
case FIT_XY:
default:
mBorderRect.set(mBounds);
mDrawableRect.set(0 + mBorderWidth, 0 + mBorderWidth, mBorderRect.width() - mBorderWidth,
mBorderRect.height() - mBorderWidth);
mShaderMatrix.set(null);
mShaderMatrix.setRectToRect(mBitmapRect, mDrawableRect, Matrix.ScaleToFit.FILL);
break;
}
mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
@Override
protected void onBoundsChange(final Rect bounds) {
super.onBoundsChange(bounds);
mBounds.set(bounds);
updateShaderMatrix();
}
@Override
public void draw(final Canvas canvas) {
if (mOval) {
if (mBorderWidth > 0) {
canvas.drawOval(mBorderRect, mBorderPaint);
canvas.drawOval(mDrawableRect, mBitmapPaint);
} else {
canvas.drawOval(mDrawableRect, mBitmapPaint);
}
} else {
if (mBorderWidth > 0) {
canvas.drawRoundRect(mBorderRect, mCornerRadius, mCornerRadius, mBorderPaint);
canvas.drawRoundRect(mDrawableRect, Math.max(mCornerRadius - mBorderWidth, 0),
Math.max(mCornerRadius - mBorderWidth, 0), mBitmapPaint);
} else {
canvas.drawRoundRect(mDrawableRect, mCornerRadius, mCornerRadius, mBitmapPaint);
}
}
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void setAlpha(final int alpha) {
mBitmapPaint.setAlpha(alpha);
invalidateSelf();
}
@Override
public void setColorFilter(final ColorFilter cf) {
mBitmapPaint.setColorFilter(cf);
invalidateSelf();
}
@Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}
@Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}
public float getCornerRadius() {
return mCornerRadius;
}
public RoundedDrawable setCornerRadius(final float radius) {
mCornerRadius = radius;
return this;
}
public float getBorderWidth() {
return mBorderWidth;
}
public RoundedDrawable setBorderWidth(final int width) {
mBorderWidth = width;
mBorderPaint.setStrokeWidth(mBorderWidth);
return this;
}
public int getBorderColor() {
return mBorderColor.getDefaultColor();
}
public RoundedDrawable setBorderColor(final int color) {
return setBorderColors(ColorStateList.valueOf(color));
}
public ColorStateList getBorderColors() {
return mBorderColor;
}
public RoundedDrawable setBorderColors(final 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(final boolean oval) {
mOval = oval;
return this;
}
public ScaleType getScaleType() {
return mScaleType;
}
public RoundedDrawable setScaleType(ScaleType scaleType) {
if (scaleType == null) {
scaleType = ScaleType.FIT_XY;
}
if (mScaleType != scaleType) {
mScaleType = scaleType;
updateShaderMatrix();
}
return this;
}
}
<强> attr.xml 强>
<declare-styleable name="RoundedImageView">
<attr name="corner_radius" format="dimension" />
<attr name="round_background" format="boolean" />
<attr name="android:scaleType" />
<!-- border -->
<attr name="border_width" format="dimension" />
<attr name="border_color" format="color" />
</declare-styleable>