The only listener I know I can attach is:
Glide.with(this)
.load(uri)
.listener(new RequestListener<Uri, GlideDrawable>() {
@Override public boolean onException(Exception e, Uri model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override public boolean onResourceReady(GlideDrawable resource, Uri model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
// easy
return false;
// impossible?
}
})
.into(imageView)
;
The // easy one: target.onResourceReady(resource, ???) has not been called yet, I don't want to handle it. I like how Glide handles this for me (return false).
The // impossible one: I want to get notified when the target already has the resource, or better yet when the animation completed and the resource has settled in the target.
Is there any way to work around this and keep the animations?
In Glide 2.0 we want back and forth on this a bit. My current thought is that you can just use a custom target class if you need this degree of control. Doing so will allow you to retain the animation, give you the ability to do something before or after the resource and/or animation is started, or entirely prevent the resource or animation from being set.
The only thing left out here is that you aren't notified when the animation completes. Unfortunately writing at would require writing our own TransitionDrawable as the framework version doesn't expose any API to listen to progress.
This came up again on Google Groups where I gave code for the above mentioned workaround:
.into(new GlideDrawableImageViewTarget(imageView) {
@Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {
// here it's similar to RequestListener, but with less information (e.g. no model available)
super.onResourceReady(resource, animation);
// here you can be sure it's already set
}
// +++++ OR +++++
@Override protected void setResource(GlideDrawable resource) {
// this.getView().setImageDrawable(resource); is about to be called
super.setResource(resource);
// here you can be sure it's already set
}
})
If you use .asBitmap() just change the above code a little: GlideDrawableImageViewTarget -> BitmapImageViewTarget and GlideDrawable -> Bitmap.
See https://github.com/bumptech/glide/wiki/Custom-targets for more info.
Leaving it open to maybe add a listener API if/when we'll have our own TransitionDrawable.
ref #1179: @TWiStErRob I tried this but I found that I get notified when the thumbnail as well as the main image loads. Is there a way to distinguish the two calls?
@chainani You can check if there's already a drawable set in the ImageView, but that's also true for thumb loads if there's a placeholder. Though still, since your custom target is a class you can store state and figure it out: for example store placeholder and compare current drawable to that. Notice that even isFirstResource doesn't tell you more than info than this. If you really want to know which one is whichyou, you can create a target that can create listeners attached to it and you can set a listener for each load (thumbnail(s) and main load) that changes the state of the target before returning false. This way when Glide calls the target lifecycle (right after return) you'll know in the target who's calling.
I don't think there's a good generic way to handle this so most use cases will have to implement some specific state transitions based on callbacks.
See ProgressTarget for a complex example.
Most helpful comment
This came up again on Google Groups where I gave code for the above mentioned workaround:
If you use
.asBitmap()just change the above code a little:GlideDrawableImageViewTarget->BitmapImageViewTargetandGlideDrawable->Bitmap.See https://github.com/bumptech/glide/wiki/Custom-targets for more info.
Leaving it open to maybe add a listener API if/when we'll have our own
TransitionDrawable.