<p dir="auto"><strong>Glide Version</strong>:<br>
3.7.0</p>

<p dir="auto"><strong>Device/Android Version</strong>:<br>
Reproduced on Android 7.0 emulator and various 6.0 devices (Nexus 5, Galaxy Note 5, others)</p>

<p dir="auto"><strong>Issue details / Repro steps / Use case background</strong>:</p>
<p dir="auto">Suppose you have two images you want to toggle between in a single, static <code class="notranslate">ImageView</code>. 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:</p>
<p dir="auto"><a href="https://gfycat.com/WillingInsignificantHypacrosaurus" rel="nofollow">https://gfycat.com/WillingInsignificantHypacrosaurus</a></p>
<p dir="auto">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 <code class="notranslate">RequestListener</code> is used to enforce Glide's <code class="notranslate">.crossfade()</code> functionality is used every time (default functionality skips the <code class="notranslate">.crossfade()</code> animation once the image has been memory-cached) :</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    public static void loadWithCrossfadeAlways(@NonNull String path, @NonNull ImageView target) {
        Glide.with(target.getContext())
                .load(path)
                .listener(new RequestListener&lt;String, GlideDrawable&gt;() {
                    @Override
                    public boolean onException(Exception e, String model, Target&lt;GlideDrawable&gt; target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(GlideDrawable resource, String model, Target&lt;GlideDrawable&gt; target, boolean isFromMemoryCache, boolean isFirstResource) {
                        ImageViewTarget imTarget = (ImageViewTarget) target;
                        return new DrawableCrossFadeFactory&lt;&gt;()
                                .build(false, isFirstResource)
                                .animate(resource, imTarget);
                    }
                })
                .into(target);
}"><pre class="notranslate">    <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-smi">void</span> <span class="pl-s1">loadWithCrossfadeAlways</span>(<span class="pl-c1">@</span><span class="pl-c1">NonNull</span> <span class="pl-smi">String</span> <span class="pl-s1">path</span>, <span class="pl-c1">@</span><span class="pl-c1">NonNull</span> <span class="pl-smi">ImageView</span> <span class="pl-s1">target</span>) {
        <span class="pl-smi">Glide</span>.<span class="pl-en">with</span>(<span class="pl-s1">target</span>.<span class="pl-en">getContext</span>())
                .<span class="pl-en">load</span>(<span class="pl-s1">path</span>)
                .<span class="pl-en">listener</span>(<span class="pl-k">new</span> <span class="pl-smi">RequestListener</span>&lt;<span class="pl-smi">String</span>, <span class="pl-smi">GlideDrawable</span>&gt;() {
                    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
                    <span class="pl-k">public</span> <span class="pl-smi">boolean</span> <span class="pl-en">onException</span>(<span class="pl-smi">Exception</span> <span class="pl-s1">e</span>, <span class="pl-smi">String</span> <span class="pl-s1">model</span>, <span class="pl-smi">Target</span>&lt;<span class="pl-smi">GlideDrawable</span>&gt; <span class="pl-s1">target</span>, <span class="pl-smi">boolean</span> <span class="pl-s1">isFirstResource</span>) {
                        <span class="pl-k">return</span> <span class="pl-c1">false</span>;
                    }

                    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
                    <span class="pl-k">public</span> <span class="pl-smi">boolean</span> <span class="pl-en">onResourceReady</span>(<span class="pl-smi">GlideDrawable</span> <span class="pl-s1">resource</span>, <span class="pl-smi">String</span> <span class="pl-s1">model</span>, <span class="pl-smi">Target</span>&lt;<span class="pl-smi">GlideDrawable</span>&gt; <span class="pl-s1">target</span>, <span class="pl-smi">boolean</span> <span class="pl-s1">isFromMemoryCache</span>, <span class="pl-smi">boolean</span> <span class="pl-s1">isFirstResource</span>) {
                        <span class="pl-smi">ImageViewTarget</span> <span class="pl-s1">imTarget</span> = (<span class="pl-smi">ImageViewTarget</span>) <span class="pl-s1">target</span>;
                        <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">DrawableCrossFadeFactory</span>&lt;&gt;()
                                .<span class="pl-en">build</span>(<span class="pl-c1">false</span>, <span class="pl-s1">isFirstResource</span>)
                                .<span class="pl-en">animate</span>(<span class="pl-s1">resource</span>, <span class="pl-s1">imTarget</span>);
                    }
                })
                .<span class="pl-en">into</span>(<span class="pl-s1">target</span>);
}</pre></div>
<p dir="auto">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:</p>
<p dir="auto"><a href="https://gfycat.com/UnfoldedVastAmurstarfish" rel="nofollow">https://gfycat.com/UnfoldedVastAmurstarfish</a></p>
<p dir="auto">The reason for this appears to be in <code class="notranslate">ImageViewTarget.onLoadStarted(Drawable placeholder)</code> and <code class="notranslate">ImageViewTarget.onLoadCleared(Drawable placeholder)</code>, both of which contain a single call to <code class="notranslate">ImageView.setImageDrawable(placeholder)</code>. 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 <strong>even if <code class="notranslate">placeholder</code> is not specified - i.e, its value is <code class="notranslate">null</code></strong>.</p>
<p dir="auto">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.</p>
<p dir="auto">In the meantime, it is possible to work around this by creating an <code class="notranslate">ImageViewTarget</code> subclass that suppresses the above-described <code class="notranslate">setImageDrawable()</code>:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="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);
        }
    }
}"><pre class="notranslate"><span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-smi">CrossfadeImageViewTarget</span> <span class="pl-k">extends</span> <span class="pl-smi">GlideDrawableImageViewTarget</span> {
    <span class="pl-k">public</span> <span class="pl-smi">CrossfadeImageViewTarget</span>(<span class="pl-smi">ImageView</span> <span class="pl-s1">view</span>) {
        <span class="pl-en">super</span>(<span class="pl-s1">view</span>);
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span> <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">onLoadStarted</span>(<span class="pl-smi">Drawable</span> <span class="pl-s1">placeholder</span>) {
        <span class="pl-k">if</span> (<span class="pl-s1">placeholder</span> != <span class="pl-c1">null</span>) {
            <span class="pl-en">super</span>.<span class="pl-en">onLoadStarted</span>(<span class="pl-s1">placeholder</span>);
        }
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span> <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">onLoadCleared</span>(<span class="pl-smi">Drawable</span> <span class="pl-s1">placeholder</span>) {
        <span class="pl-k">if</span> (<span class="pl-s1">placeholder</span> != <span class="pl-c1">null</span>) {
            <span class="pl-en">super</span>.<span class="pl-en">onLoadCleared</span>(<span class="pl-s1">placeholder</span>);
        }
    }
}</pre></div>
<p dir="auto">Using this subclass as the target in the above loader method produces the intended result.</p>
<p dir="auto"><strong>Glide Version</strong>: 4.2.0<br>
<strong>Integration libraries</strong>: none</p>
<p dir="auto"><strong>Issue details</strong>:  I have an <code class="notranslate">ImageView</code> that needs to be refreshed often, but each time there is a change the image <strong>flickers</strong> white (unless it is present in the memory cache).</p>
<p dir="auto">This must be the default behavior, as I can see in the basic lifecycle of a <code class="notranslate">Glide</code> request:</p>
<ol dir="auto">
<li>Cancel any in progress load for the View and/or <strong>clear out any current image</strong> and recycle its resource.</li>
<li>Set the placeholder drawable</li>
<li>Start the image load</li>
<li>If it completes synchronously (from the memory cache) set the image on the View and do not animate.</li>
<li>If it completes asynchronously, set the image on the View and animate.</li>
</ol>
<p dir="auto">Is there a way to <strong>disable the default clearing</strong> of the <code class="notranslate">ImageView</code> on step 1) <strong>until the next image is loaded</strong> in order to prevent the flicker?</p>
<p dir="auto">The following works, but I was wondering if there is a simpler solution, for example by disabling animations. I read something about a <code class="notranslate">dontAnimate()</code> method but can't find it on <code class="notranslate">4.2.0</code>.</p>
<div class="highlight highlight-source-kotlin notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="Glide
    .with(thisActivity)
    .asBitmap()
    .load(someUrl)
    .into(object : SimpleTarget&lt;Bitmap&gt;() {
        override fun onResourceReady(resource: Bitmap, transition: Transition&lt;in Bitmap&gt;) {
            imageView.setImageBitmap(resource)
        }
    })"><pre class="notranslate"><span class="pl-en">Glide</span>
    .<span class="pl-c1">with</span>(thisActivity)
    .asBitmap()
    .load(someUrl)
    .into(<span class="pl-k">object</span> <span class="pl-k">:</span> <span class="pl-en">SimpleTarget</span>&lt;<span class="pl-en">Bitmap</span>&gt;() {
        <span class="pl-k">override</span> <span class="pl-k">fun</span> <span class="pl-en">onResourceReady</span>(<span class="pl-smi">resource</span><span class="pl-k">:</span> <span class="pl-en">Bitmap</span>, <span class="pl-smi">transition</span><span class="pl-k">:</span> <span class="pl-en">Transition</span>&lt;<span class="pl-k">in</span> <span class="pl-en">Bitmap</span>&gt;) {
            imageView.setImageBitmap(resource)
        }
    })</pre></div>