Issue 1:
Glide Version:

3.7.0

Device/Android Version:

Reproduced on Android 7.0 emulator and various 6.0 devices (Nexus 5, Galaxy Note 5, others)

Issue details / Repro steps / Use case background:

Suppose you have two images you want to toggle between in a single, static ImageView. They're both memory-cached and so can theoretically display immediately upon toggle, but to create a nicer user experience, you'd like to fade out the previous image at the same time that you fade in the new image. The resulting animation - composed of two fade animations at the same time - is what most designers refer to as a "crossfade". It looks something like this:

https://gfycat.com/WillingInsignificantHypacrosaurus

Unfortunately, this is not the default behavior of Glide, although it does appear to be the intention. Consider the following Glide load call, where the RequestListener is used to enforce Glide's .crossfade() functionality is used every time (default functionality skips the .crossfade() animation once the image has been memory-cached) :

public static void loadWithCrossfadeAlways(@NonNull String path, @NonNull ImageView target) {
Glide.with(target.getContext())
.load(path)
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}

@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
ImageViewTarget imTarget = (ImageViewTarget) target;
return new DrawableCrossFadeFactory<>()
.build(false, isFirstResource)
.animate(resource, imTarget);
}
})
.into(target);
}

The result does not produce a true crossfade, but instead immediately removes the original image, and fades the new image in over the background of the View:

https://gfycat.com/UnfoldedVastAmurstarfish

The reason for this appears to be in ImageViewTarget.onLoadStarted(Drawable placeholder) and ImageViewTarget.onLoadCleared(Drawable placeholder), both of which contain a single call to ImageView.setImageDrawable(placeholder). The reasoning for this call's presence is self evident - it's how the specified placeholder image gets rendered - but it prevents a smooth crossfade from occurring, and worse yet, does so even if placeholder is not specified - i.e, its value is null.

Ideally, the placeholder would be crossfaded in (as the previous image fades out) and then crossfaded out (as the new image fades in), or in the case of a missing placeholder or memory-cached image, omitted altogether.

In the meantime, it is possible to work around this by creating an ImageViewTarget subclass that suppresses the above-described setImageDrawable():

public class CrossfadeImageViewTarget extends GlideDrawableImageViewTarget {
public CrossfadeImageViewTarget(ImageView view) {
super(view);
}

@Override public void onLoadStarted(Drawable placeholder) {
if (placeholder != null) {
super.onLoadStarted(placeholder);
}
}

@Override public void onLoadCleared(Drawable placeholder) {
if (placeholder != null) {
super.onLoadCleared(placeholder);
}
}
}

Using this subclass as the target in the above loader method produces the intended result.

Issue 2:
Glide Version: 4.2.0

Integration libraries: none

Issue details: I have an ImageView that needs to be refreshed often, but each time there is a change the image flickers white (unless it is present in the memory cache).

This must be the default behavior, as I can see in the basic lifecycle of a Glide request:

Cancel any in progress load for the View and/or clear out any current image and recycle its resource.

Set the placeholder drawable

Start the image load

If it completes synchronously (from the memory cache) set the image on the View and do not animate.

If it completes asynchronously, set the image on the View and animate.

Is there a way to disable the default clearing of the ImageView on step 1) until the next image is loaded in order to prevent the flicker?

The following works, but I was wondering if there is a simpler solution, for example by disabling animations. I read something about a dontAnimate() method but can't find it on 4.2.0.

Glide
.with(thisActivity)
.asBitmap()
.load(someUrl)
.into(object : SimpleTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>) {
imageView.setImageBitmap(resource)
}
})