I want to show a roundedimage so I use this https://github.com/vinc3m1/RoundedImageView
in my xml
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/item_profile_image"
android:layout_width="40dip"
android:layout_height="40dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:layout_marginTop="10.0dip"
android:scaleType="centerCrop"
android:src="@drawable/avatar_regular"
app:riv_corner_radius="40dp"/>
and glide use like this
Glide.with(context).load(url).crossFade().diskCacheStrategy(DiskCacheStrategy.RESULT).centerCrop().placeholder(R.drawable.avatar_regular).into(iv);
when the listView load but the image can not show direct,but when I scroll back it show
if i dont set placeholder,There is no problem
Glide不会立即替换占位图,你需要改变into()这个方法里的参数为一个callback targets.例如:
Glide.with(mContext)
.load(imageUrl)
.centerCrop()
.crossFade()
.placeholder(R.drawable.list_image_default_header)
.into(target);
private SimpleTarget target = new SimpleTarget<GlideBitmapDrawable>() {
@Override
public void onResourceReady(GlideBitmapDrawable bitmap, GlideAnimation glideAnimation) {
// do something with the bitmap
// for demonstration purposes, let's just set it to an ImageView
//mImageView.setBackground(bitmap);
//mImageView.setImageDrawable(bitmap);
mImageView.setImageBitmap(bitmap.getBitmap());
}
};
@chongzi 不是占位图被不被替换的问题,如果不用圆形图控件,正常的ImageView 没有问题,但是用圆形图控件的,并设置占位图,图片加载完后不会显示,上下滚动ListView后显示出来了
Here's a nice list. We dug deep and found the core of the problem: https://github.com/bumptech/glide/issues/482#issuecomment-107977982 (_scroll down a little, the images may make the URL anchor displaced, it's the last long comment by me_)
You have two options:
.dontAnimate()While disabling the animation seems easier, you may have more luck with the transformation in the long run.
@chongzi please keep it English, and that SimpleTarget workaround may seem to work at first, but it leaks the Bitmap and it is unsafe (the Bitmap may be recycled without you knowing it).
as @TWiStErRob said,you maybe use CirCleCrop, other way is use follow CirlCleImageView . my test show success.
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.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.nfdaily.nfplus.R;
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 static final boolean DEFAULT_BORDER_OVERLAY = false;
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 ColorFilter mColorFilter;
private boolean mReady;
private boolean mSetupPending;
private boolean mBorderOverlay;
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);
mBorderOverlay = a.getBoolean(
R.styleable.CircleImageView_border_overlay,
DEFAULT_BORDER_OVERLAY);
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 void setBorderColorResource(@ColorRes int borderColorRes) {
setBorderColor(getContext().getResources().getColor(borderColorRes));
}
public int getBorderWidth() {
return mBorderWidth;
}
public void setBorderWidth(int borderWidth) {
if (borderWidth == mBorderWidth) {
return;
}
mBorderWidth = borderWidth;
setup();
}
public boolean isBorderOverlay() {
return mBorderOverlay;
}
public void setBorderOverlay(boolean borderOverlay) {
if (borderOverlay == mBorderOverlay) {
return;
}
mBorderOverlay = borderOverlay;
setup();
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
mBitmap = bm;
setup();
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
mBitmap = getBitmapFromDrawable(drawable);
setup();
}
@Override
public void setImageResource(@DrawableRes int resId) {
super.setImageResource(resId);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
@Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
@Override
public void setColorFilter(ColorFilter cf) {
if (cf == mColorFilter) {
return;
}
mColorFilter = cf;
mBitmapPaint.setColorFilter(mColorFilter);
invalidate();
}
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) {
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(mBorderRect);
if (!mBorderOverlay) {
mDrawableRect.inset(mBorderWidth, 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) + mDrawableRect.left,
(int) (dy + 0.5f) + mDrawableRect.top);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
}
@chongzi It doesn't matter what you call these custom image views: Rounded/Circle/Circular, the key is always whether it has getBitmapFromDrawable.
You can see with very little reasoning that it is incompatible with any Drawable that changes over time (drawable.draw(canvas) captures a single moment in time and caches it), that any time you call the draw method you may get a different result. This includes TransitionDrawable (result of .placeholder().crossFade()) and GIF Drawables, or any animated vector drawable.
The only way these custom views would work if they create a mask during ImageView.onDraw and call drawable.draw(canvas) there to draw inside a constrained circular area.
can I put color like this placeholder(R.color.colorAccent) orplaceholder(Color.parseColor("#303F9F"));
No, placeholder only accepts Drawable or @DrawableRes int if you want colors you can do:
.placeholder(new ColorDrawable(ContextCompat.getColor(context, R.color.colorAccent)));
.placeholder(new ColorDrawable(Color.parseColor("#303F9F")));
Most helpful comment
Here's a nice list. We dug deep and found the core of the problem: https://github.com/bumptech/glide/issues/482#issuecomment-107977982 (_scroll down a little, the images may make the URL anchor displaced, it's the last long comment by me_)
You have two options:
.dontAnimate()While disabling the animation seems easier, you may have more luck with the transformation in the long run.
@chongzi please keep it English, and that
SimpleTargetworkaround may seem to work at first, but it leaks the Bitmap and it is unsafe (the Bitmap may be recycled without you knowing it).