diff --git a/library/src/androidTest/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimationTest.java b/library/src/androidTest/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimationTest.java index 78190b32428792ea9bd2da9f74d5842d5097b6d4..a4b902486f8c879c9e5166f5fbff404ecb7c052b 100644 --- a/library/src/androidTest/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimationTest.java +++ b/library/src/androidTest/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimationTest.java @@ -4,10 +4,7 @@ import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.TransitionDrawable; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; import android.widget.ImageView; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -17,6 +14,7 @@ import static com.bumptech.glide.request.animation.GlideAnimation.ViewAdapter; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -34,7 +32,7 @@ public class DrawableCrossFadeViewAnimationTest { public void testStartsDefaultAnimationIfNoPreviousDrawableIsNotSet() { when(harness.adapter.getView()).thenReturn(harness.view); harness.animation.animate(harness.current, harness.adapter); - verify(harness.view).startAnimation(any(Animation.class)); + verify(harness.defaultAnimation).animate(eq(harness.current), eq(harness.adapter)); } @Test @@ -69,7 +67,7 @@ public class DrawableCrossFadeViewAnimationTest { Drawable current = new ColorDrawable(Color.GRAY); ViewAdapter adapter = mock(ViewAdapter.class); ImageView view = mock(ImageView.class); - Animation defaultAnimation = new AlphaAnimation(0f, 1f); + GlideAnimation defaultAnimation = mock(GlideAnimation.class); int duration = 200; DrawableCrossFadeViewAnimation animation = new DrawableCrossFadeViewAnimation( defaultAnimation, duration); diff --git a/library/src/androidTest/java/com/bumptech/glide/request/animation/ViewAnimationTest.java b/library/src/androidTest/java/com/bumptech/glide/request/animation/ViewAnimationTest.java index 163cd53d3c735149f77967f1be6b9f0f100187fd..6d167a3641a8d8c60875f08b4f18f476584cfb26 100644 --- a/library/src/androidTest/java/com/bumptech/glide/request/animation/ViewAnimationTest.java +++ b/library/src/androidTest/java/com/bumptech/glide/request/animation/ViewAnimationTest.java @@ -1,8 +1,7 @@ package com.bumptech.glide.request.animation; -import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; import android.widget.ImageView; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -17,19 +16,19 @@ import static org.mockito.Mockito.when; @RunWith(RobolectricTestRunner.class) public class ViewAnimationTest { - private AlphaAnimation animation; - private ViewAnimation viewAnimation; + private ViewAnimation viewAnimation; private ViewAdapter adapter; private ImageView view; + private ViewAnimation.AnimationFactory animationFactory; @SuppressWarnings("unchecked") @Before public void setUp() { - animation = new AlphaAnimation(0f, 1f); + animationFactory = mock(ViewAnimation.AnimationFactory.class); view = mock(ImageView.class); adapter = mock(ViewAdapter.class); when(adapter.getView()).thenReturn(view); - viewAnimation = new ViewAnimation(animation); + viewAnimation = new ViewAnimation(animationFactory); } @Test @@ -46,7 +45,10 @@ public class ViewAnimationTest { @Test public void testStartsAnimationOnAnimate() { + Animation animation = mock(Animation.class); + when(animationFactory.build()).thenReturn(animation); viewAnimation.animate(null, adapter); + verify(view).clearAnimation(); verify(view).startAnimation(eq(animation)); } } diff --git a/library/src/main/java/com/bumptech/glide/BitmapRequestBuilder.java b/library/src/main/java/com/bumptech/glide/BitmapRequestBuilder.java index d54e79800349b780e047e81761954dd53612f374..b15819cfea0f0e4d30b862cfd0824f4fb2d374e6 100644 --- a/library/src/main/java/com/bumptech/glide/BitmapRequestBuilder.java +++ b/library/src/main/java/com/bumptech/glide/BitmapRequestBuilder.java @@ -331,6 +331,8 @@ public class BitmapRequestBuilder /** * {@inheritDoc} */ + @Deprecated + @SuppressWarnings("deprecation") @Override public BitmapRequestBuilder animate(Animation animation) { super.animate(animation); diff --git a/library/src/main/java/com/bumptech/glide/DrawableOptions.java b/library/src/main/java/com/bumptech/glide/DrawableOptions.java index 95e9c3ec7effa4cad7bce042771240ccf451d8b1..74e7eae9ed89fc6322b6761709366cb1add632d4 100644 --- a/library/src/main/java/com/bumptech/glide/DrawableOptions.java +++ b/library/src/main/java/com/bumptech/glide/DrawableOptions.java @@ -10,7 +10,6 @@ interface DrawableOptions { * * @see #crossFade(int) * @see #crossFade(int, int) - * @see #crossFade(android.view.animation.Animation, int) * * @return This request builder. */ @@ -22,7 +21,6 @@ interface DrawableOptions { * * @see #crossFade() * @see #crossFade(int, int) - * @see #crossFade(android.view.animation.Animation, int) * * @param duration The duration of the cross fade and initial fade in. * @return This request builder. @@ -39,13 +37,17 @@ interface DrawableOptions { * @see #crossFade(int) * @see #crossFade(int, int) * + * @deprecated If this builder is used for multiple loads, using this method will result in multiple view's being + * asked to start an animation using a single {@link android.view.animation.Animation} object which results in + * views animating repeatedly. Use {@link #crossFade(int, int)}} instead, or be sure to call this method once + * per call to {@link com.bumptech.glide.GenericRequestBuilder#load(Object)} to avoid re-using animation objects. * @param animation The Animation to use if no placeholder is set. * @param duration The duration of the cross fade animation. * @return This request builder. */ + @Deprecated GenericRequestBuilder crossFade(Animation animation, int duration); - /** * Applies a cross fade transformation that des from the placeholder to the loaded * {@link android.graphics.drawable.Drawable}. If no placeholder is set, the Drawable will instead be animated in @@ -53,7 +55,6 @@ interface DrawableOptions { * * @see #crossFade() * @see #crossFade(int) - * @see #crossFade(android.view.animation.Animation, int) * * @param animationId The id of the Animation to use if no placeholder is set. * @param duration The duration of the cross fade animation. diff --git a/library/src/main/java/com/bumptech/glide/DrawableRequestBuilder.java b/library/src/main/java/com/bumptech/glide/DrawableRequestBuilder.java index ce01593a11ab95645f40aaaa4ad67ad53e013d33..187aebd9160dbfbdfaf892940b596b0287b38480 100644 --- a/library/src/main/java/com/bumptech/glide/DrawableRequestBuilder.java +++ b/library/src/main/java/com/bumptech/glide/DrawableRequestBuilder.java @@ -257,6 +257,7 @@ public class DrawableRequestBuilder /** * {@inheritDoc} */ + @Deprecated public DrawableRequestBuilder crossFade(Animation animation, int duration) { super.animate(new DrawableCrossFadeViewAnimation.DrawableCrossFadeFactory(animation, duration)); return this; @@ -301,6 +302,8 @@ public class DrawableRequestBuilder /** * {@inheritDoc} */ + @Deprecated + @SuppressWarnings("deprecation") @Override public DrawableRequestBuilder animate(Animation animation) { super.animate(animation); diff --git a/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java b/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java index 50cfc76d38593cd36fdaaae594186f237b745013..698d58e0d919f93378665498cb0df542307534e3 100644 --- a/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java +++ b/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java @@ -366,9 +366,7 @@ public class GenericRequestBuilder animate( - int animationId) { + public GenericRequestBuilder animate(int animationId) { return animate(new ViewAnimation.ViewAnimationFactory(context, animationId)); } @@ -376,12 +374,18 @@ public class GenericRequestBuilder animate( - Animation animation) { + @Deprecated + public GenericRequestBuilder animate(Animation animation) { return animate(new ViewAnimation.ViewAnimationFactory(animation)); } @@ -393,7 +397,6 @@ public class GenericRequestBuilder animate( ViewPropertyAnimation.Animator animator) { return animate(new ViewPropertyAnimation.ViewPropertyAnimationFactory(animator)); diff --git a/library/src/main/java/com/bumptech/glide/GifRequestBuilder.java b/library/src/main/java/com/bumptech/glide/GifRequestBuilder.java index d6918f68e2156109e073e3444f486f311104b129..de9330f5bc7ff9368d0a6deabb39b6ace6078ac9 100644 --- a/library/src/main/java/com/bumptech/glide/GifRequestBuilder.java +++ b/library/src/main/java/com/bumptech/glide/GifRequestBuilder.java @@ -245,6 +245,7 @@ public class GifRequestBuilder /** * {@inheritDoc} */ + @Deprecated @Override public GifRequestBuilder crossFade(Animation animation, int duration) { super.animate(new DrawableCrossFadeViewAnimation.DrawableCrossFadeFactory(animation, duration)); @@ -282,6 +283,8 @@ public class GifRequestBuilder /** * {@inheritDoc} */ + @Deprecated + @SuppressWarnings("deprecation") @Override public GifRequestBuilder animate(Animation animation) { super.animate(animation); diff --git a/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimation.java b/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimation.java index 1623d6d6589a27f35accd929471e52cb18538346..bf2d3eeae4cef07e02d5244aae646079524af0fb 100644 --- a/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimation.java +++ b/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimation.java @@ -3,10 +3,8 @@ package com.bumptech.glide.request.animation; import android.content.Context; import android.graphics.drawable.Drawable; import android.graphics.drawable.TransitionDrawable; -import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; -import android.view.animation.AnimationUtils; /** * A cross fade {@link GlideAnimation} for {@link android.graphics.drawable.Drawable}s @@ -19,15 +17,9 @@ import android.view.animation.AnimationUtils; public class DrawableCrossFadeViewAnimation implements GlideAnimation { // 150 ms. public static final int DEFAULT_DURATION = 300; - private final Animation defaultAnimation; + private final GlideAnimation defaultAnimation; private final int duration; - private static Animation getDefaultAnimation() { - AlphaAnimation animation = new AlphaAnimation(0f, 1f); - animation.setDuration(DEFAULT_DURATION / 2); - return animation; - } - /** * A factory class that produces a new {@link GlideAnimation} that varies depending * on whether or not the drawable was loaded from the memory cache and whether or not the drawable is the first @@ -41,28 +33,28 @@ public class DrawableCrossFadeViewAnimation implements Glide *

*/ public static class DrawableCrossFadeFactory implements GlideAnimationFactory { - private Context context; - private int defaultAnimationId; - private Animation defaultAnimation; - private int duration; + private final ViewAnimation.ViewAnimationFactory animationFactory; + private final int duration; private DrawableCrossFadeViewAnimation animation; public DrawableCrossFadeFactory() { - this(getDefaultAnimation(), DEFAULT_DURATION); + this(DEFAULT_DURATION); } public DrawableCrossFadeFactory(int duration) { - this(getDefaultAnimation(), duration); + this(new ViewAnimation.ViewAnimationFactory(new DefaultAnimationFactory()), duration); } public DrawableCrossFadeFactory(Context context, int defaultAnimationId, int duration) { - this.context = context; - this.defaultAnimationId = defaultAnimationId; - this.duration = duration; + this(new ViewAnimation.ViewAnimationFactory(context, defaultAnimationId), duration); } public DrawableCrossFadeFactory(Animation defaultAnimation, int duration) { - this.defaultAnimation = defaultAnimation; + this(new ViewAnimation.ViewAnimationFactory(defaultAnimation), duration); + } + + DrawableCrossFadeFactory(ViewAnimation.ViewAnimationFactory animationFactory, int duration) { + this.animationFactory = animationFactory; this.duration = duration; } @@ -73,9 +65,7 @@ public class DrawableCrossFadeViewAnimation implements Glide } if (animation == null) { - if (defaultAnimation == null) { - defaultAnimation = AnimationUtils.loadAnimation(context, defaultAnimationId); - } + GlideAnimation defaultAnimation = animationFactory.build(false, isFirstResource); animation = new DrawableCrossFadeViewAnimation(defaultAnimation, duration); } @@ -86,12 +76,10 @@ public class DrawableCrossFadeViewAnimation implements Glide /** * Constructor that takes a default animation and a duration in milliseconds that the cross fade animation should * last. - * @param defaultAnimation The default animation that will run if there is nothing to cross fade from when a new - * {@link android.graphics.drawable.Drawable} is set. * @param duration The duration that the cross fade animation should run if there is something to cross fade from * when a new {@link android.graphics.drawable.Drawable} is set. */ - public DrawableCrossFadeViewAnimation(Animation defaultAnimation, int duration) { + public DrawableCrossFadeViewAnimation(GlideAnimation defaultAnimation, int duration) { this.defaultAnimation = defaultAnimation; this.duration = duration; } @@ -119,11 +107,18 @@ public class DrawableCrossFadeViewAnimation implements Glide adapter.setDrawable(transitionDrawable); return true; } else { - View view = adapter.getView(); - if (view != null) { - view.startAnimation(defaultAnimation); - } + defaultAnimation.animate(current, adapter); return false; } } + + private static class DefaultAnimationFactory implements ViewAnimation.AnimationFactory { + + @Override + public Animation build() { + AlphaAnimation animation = new AlphaAnimation(0f, 1f); + animation.setDuration(DEFAULT_DURATION / 2); + return animation; + } + } } diff --git a/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimation.java b/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimation.java index 72fc8b7d17ba2520aa3f095bcccea96fcbe0aa64..aeea7187891d4eb484c339588ea5d5cf907fb0cb 100644 --- a/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimation.java +++ b/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimation.java @@ -14,14 +14,13 @@ import android.view.animation.AnimationUtils; */ public class ViewAnimation implements GlideAnimation { - private final Animation animation; + private final AnimationFactory animationFactory; /** * Constructs a new ViewAnimation that will start the given {@link android.view.animation.Animation}. - * @param animation The animation to use. */ - public ViewAnimation(Animation animation) { - this.animation = animation; + ViewAnimation(AnimationFactory animationFactory) { + this.animationFactory = animationFactory; } /** @@ -39,7 +38,7 @@ public class ViewAnimation implements GlideAnimation { View view = adapter.getView(); if (view != null) { view.clearAnimation(); - + Animation animation = animationFactory.build(); view.startAnimation(animation); } @@ -50,18 +49,19 @@ public class ViewAnimation implements GlideAnimation { * A {@link com.bumptech.glide.request.animation.GlideAnimationFactory} that produces ViewAnimations. */ public static class ViewAnimationFactory implements GlideAnimationFactory { - private Animation animation; - private Context context; - private int animationId; + private final AnimationFactory animationFactory; private GlideAnimation glideAnimation; public ViewAnimationFactory(Animation animation) { - this.animation = animation; + this(new ConcreteAnimationFactory(animation)); } public ViewAnimationFactory(Context context, int animationId) { - this.context = context; - this.animationId = animationId; + this(new ResourceAnimationFactory(context, animationId)); + } + + ViewAnimationFactory(AnimationFactory animationFactory) { + this.animationFactory = animationFactory; } /** @@ -80,13 +80,42 @@ public class ViewAnimation implements GlideAnimation { } if (glideAnimation == null) { - if (animation == null) { - animation = AnimationUtils.loadAnimation(context, animationId); - } - glideAnimation = new ViewAnimation(animation); + glideAnimation = new ViewAnimation(animationFactory); } return glideAnimation; } } + + private static class ConcreteAnimationFactory implements AnimationFactory { + private final Animation animation; + + public ConcreteAnimationFactory(Animation animation) { + this.animation = animation; + } + + @Override + public Animation build() { + return animation; + } + } + + private static class ResourceAnimationFactory implements AnimationFactory { + private final Context context; + private final int animationId; + + public ResourceAnimationFactory(Context context, int animationId) { + this.context = context.getApplicationContext(); + this.animationId = animationId; + } + + @Override + public Animation build() { + return AnimationUtils.loadAnimation(context, animationId); + } + } + + interface AnimationFactory { + Animation build(); + } }