aboutsummaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorSam Judd <judds@google.com>2014-06-27 15:40:34 -0700
committerSam Judd <judds@google.com>2014-06-27 16:04:52 -0700
commit4f579a81caf5c4ff505bb8d48d903062a52254bd (patch)
treed65ebf04b160bc639aae5fb737bde11d2b890782 /library
parent53c16e03081b659c2c9009721b1a50728d4fae80 (diff)
downloadglide-4f579a81caf5c4ff505bb8d48d903062a52254bd.tar.gz
Fix Gifs not appearing.
Diffstat (limited to 'library')
-rw-r--r--library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java7
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameManager.java7
-rw-r--r--library/src/main/java/com/bumptech/glide/request/target/DrawableImageViewTarget.java25
-rw-r--r--library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java3
-rw-r--r--library/src/test/java/com/bumptech/glide/GenericRequestBuilderTest.java11
-rw-r--r--library/src/test/java/com/bumptech/glide/request/target/DrawableImageViewTargetTest.java212
-rw-r--r--library/src/test/java/com/bumptech/glide/request/target/ViewTargetTest.java14
7 files changed, 266 insertions, 13 deletions
diff --git a/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java b/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
index 30e3051b..27fd7cae 100644
--- a/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
+++ b/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
@@ -521,6 +521,10 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
* @return The given target.
*/
public <Y extends Target<TranscodeType>> Y into(Y target) {
+ if (target == null) {
+ throw new IllegalArgumentException("You must pass in a non null Target");
+ }
+
Request previous = target.getRequest();
if (previous != null) {
@@ -547,6 +551,9 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
* @return The {@link BitmapImageViewTarget} used to wrap the given {@link ImageView}.
*/
public Target<TranscodeType> into(ImageView view) {
+ if (view == null) {
+ throw new IllegalArgumentException("You must pass in a non null View");
+ }
return into(glide.buildImageViewTarget(view, transcodeClass));
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameManager.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameManager.java
index 281c1ad7..254f30e6 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameManager.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameManager.java
@@ -13,6 +13,7 @@ import com.bumptech.glide.load.SkipCache;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.engine.cache.MemorySizeCalculator;
+import com.bumptech.glide.load.model.NullEncoder;
import com.bumptech.glide.load.resource.NullDecoder;
import com.bumptech.glide.load.resource.bitmap.BitmapEncoder;
import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder;
@@ -32,7 +33,7 @@ class GifFrameManager {
private final Handler mainHandler;
private final ResourceEncoder<Bitmap> encoder;
private final Context context;
-
+ private final NullEncoder<GifDecoder> sourceEncoder;
private Transformation<Bitmap> transformation;
private final int targetWidth;
private final int targetHeight;
@@ -61,6 +62,7 @@ class GifFrameManager {
calculator = new MemorySizeCalculator(context);
frameLoader = new GifFrameModelLoader();
frameResourceDecoder = new GifFrameResourceDecoder(bitmapPool);
+ sourceEncoder = NullEncoder.get();
if (!decoder.isTransparent()) {
// For non transparent gifs, we can beat the performance of our gif decoder for each frame by decoding jpegs
@@ -100,10 +102,11 @@ class GifFrameManager {
.using(frameLoader, GifDecoder.class)
.load(decoder)
.as(Bitmap.class)
+ .sourceEncoder(sourceEncoder)
.decoder(frameResourceDecoder)
.cacheDecoder(cacheDecoder)
- .transform(transformation)
.encoder(encoder)
+ .transform(transformation)
.skipMemoryCache(skipCache)
.into(next);
}
diff --git a/library/src/main/java/com/bumptech/glide/request/target/DrawableImageViewTarget.java b/library/src/main/java/com/bumptech/glide/request/target/DrawableImageViewTarget.java
index 8fbd0e48..9c298264 100644
--- a/library/src/main/java/com/bumptech/glide/request/target/DrawableImageViewTarget.java
+++ b/library/src/main/java/com/bumptech/glide/request/target/DrawableImageViewTarget.java
@@ -1,5 +1,6 @@
package com.bumptech.glide.request.target;
+import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import com.bumptech.glide.request.GlideAnimation;
@@ -15,17 +16,19 @@ public class DrawableImageViewTarget extends ViewTarget<ImageView, Drawable> {
@Override
public void onResourceReady(Drawable resource, GlideAnimation<Drawable> animation) {
-
- //TODO: Try to generalize this to other sizes/shapes.
- // This is a dirty hack that tries to make loading square thumbnails and then square full images less costly by
- // forcing both the smaller thumb and the larger version to have exactly the same intrinsic dimensions. If a
- // drawable is replaced in an ImageView by another drawable with different intrinsic dimensions, the ImageView
- // requests a layout. Scrolling rapidly while replacing thumbs with larger images triggers lots of these calls
- // and causes significant amounts of jank.
- float viewRatio = view.getWidth() / (float) view.getHeight();
- float drawableRatio = resource.getIntrinsicWidth() / (float) resource.getIntrinsicHeight();
- if (Math.abs(viewRatio - 1f) <= SQUARE_RATIO_MARGIN && Math.abs(drawableRatio - 1f) <= SQUARE_RATIO_MARGIN) {
- resource = new SquaringDrawable(resource, view.getWidth());
+ if (!(resource instanceof Animatable)) {
+ //TODO: Try to generalize this to other sizes/shapes.
+ // This is a dirty hack that tries to make loading square thumbnails and then square full images less costly by
+ // forcing both the smaller thumb and the larger version to have exactly the same intrinsic dimensions. If a
+ // drawable is replaced in an ImageView by another drawable with different intrinsic dimensions, the ImageView
+ // requests a layout. Scrolling rapidly while replacing thumbs with larger images triggers lots of these calls
+ // and causes significant amounts of jank.
+ float viewRatio = view.getWidth() / (float) view.getHeight();
+ float drawableRatio = resource.getIntrinsicWidth() / (float) resource.getIntrinsicHeight();
+ if (Math.abs(viewRatio - 1f) <= SQUARE_RATIO_MARGIN &&
+ Math.abs(drawableRatio - 1f) <= SQUARE_RATIO_MARGIN) {
+ resource = new SquaringDrawable(resource, view.getWidth());
+ }
}
if (animation == null || !animation.animate(view.getDrawable(), resource, view, this)) {
diff --git a/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java b/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java
index 5f77d534..e4179aff 100644
--- a/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java
+++ b/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java
@@ -40,6 +40,9 @@ public abstract class ViewTarget<T extends View, Z> implements Target<Z> {
private final SizeDeterminer sizeDeterminer;
public ViewTarget(T view) {
+ if (view == null) {
+ throw new NullPointerException("View must not be null!");
+ }
this.view = view;
sizeDeterminer = new SizeDeterminer(view);
}
diff --git a/library/src/test/java/com/bumptech/glide/GenericRequestBuilderTest.java b/library/src/test/java/com/bumptech/glide/GenericRequestBuilderTest.java
index baaf1fc5..b3c96924 100644
--- a/library/src/test/java/com/bumptech/glide/GenericRequestBuilderTest.java
+++ b/library/src/test/java/com/bumptech/glide/GenericRequestBuilderTest.java
@@ -1,5 +1,6 @@
package com.bumptech.glide;
+import android.widget.ImageView;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.ResourceEncoder;
import com.bumptech.glide.manager.RequestTracker;
@@ -114,6 +115,16 @@ public class GenericRequestBuilderTest {
verify(requestTracker).removeRequest(eq(previous));
}
+ @Test(expected = IllegalArgumentException.class)
+ public void testThrowsIfGivenNullTarget() {
+ getNullModelRequest().into((Target) null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testThrowsIfGivenNullView() {
+ getNullModelRequest().into((ImageView) null);
+ }
+
private GenericRequestBuilder getNullModelRequest() {
return new GenericRequestBuilder(Robolectric.application, null, null, Object.class, mock(Glide.class),
requestTracker);
diff --git a/library/src/test/java/com/bumptech/glide/request/target/DrawableImageViewTargetTest.java b/library/src/test/java/com/bumptech/glide/request/target/DrawableImageViewTargetTest.java
new file mode 100644
index 00000000..6caa833f
--- /dev/null
+++ b/library/src/test/java/com/bumptech/glide/request/target/DrawableImageViewTargetTest.java
@@ -0,0 +1,212 @@
+package com.bumptech.glide.request.target;
+
+import android.graphics.Color;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.ImageView;
+import com.bumptech.glide.request.GlideAnimation;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(RobolectricTestRunner.class)
+public class DrawableImageViewTargetTest {
+ private ImageView view;
+ private DrawableImageViewTarget target;
+
+ @Before
+ public void setUp() {
+ view = new ImageView(Robolectric.application);
+ target = new DrawableImageViewTarget(view);
+ }
+
+ @Test
+ public void testSetsDrawableOnViewInOnResourceReadyWhenAnimationIsNull() {
+ Drawable resource = new ColorDrawable(Color.BLUE);
+ target.onResourceReady(resource, null);
+
+ assertEquals(resource, view.getDrawable());
+ }
+
+ @Test
+ public void testSetsDrawableOnViewInOnResourceReadyWhenAnimationReturnsFalse() {
+ GlideAnimation animation = mock(GlideAnimation.class);
+ when(animation.animate(any(Drawable.class), any(Drawable.class), any(View.class), any(Target.class)))
+ .thenReturn(false);
+ Drawable resource = new ColorDrawable(Color.GRAY);
+ target.onResourceReady(resource, animation);
+
+ assertEquals(resource, view.getDrawable());
+ }
+
+ @Test
+ public void testDoesNotSetDrawableOnViewInOnResourceReadyWhenAnimationReturnsTrue() {
+ Drawable resource = new ColorDrawable(Color.RED);
+ GlideAnimation animation = mock(GlideAnimation.class);
+ when(animation.animate((Drawable) isNull(), eq(resource), eq(view), eq(target))).thenReturn(true);
+ target.onResourceReady(resource, animation);
+
+ assertNull(view.getDrawable());
+ }
+
+ @Test
+ public void testSetsPlaceholderOnView() {
+ Drawable placeholder = new ColorDrawable(Color.RED);
+ target.setPlaceholder(placeholder);
+
+ assertEquals(placeholder, view.getDrawable());
+ }
+
+ @Test
+ public void testProvidesCurrentPlaceholderToAnimationIfPresent() {
+ Drawable placeholder = new ColorDrawable(Color.BLACK);
+ view.setImageDrawable(placeholder);
+
+ GlideAnimation animation = mock(GlideAnimation.class);
+
+ target.onResourceReady(new ColorDrawable(Color.GREEN), animation);
+
+ verify(animation).animate(eq(placeholder), any(Drawable.class), any(View.class), any(Target.class));
+ }
+
+ @Test
+ public void testWrapsDrawableInSquaringDrawableIfDrawableAndViewAreSquare() {
+ ImageView mockView = mock(ImageView.class);
+ when(mockView.getWidth()).thenReturn(100);
+ when(mockView.getHeight()).thenReturn(100);
+ DrawableImageViewTarget target = new DrawableImageViewTarget(mockView);
+ Drawable drawable = new ColorDrawable(Color.RED) {
+ @Override
+ public int getIntrinsicHeight() {
+ return 100;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return 100;
+ }
+ };
+
+
+ target.onResourceReady(drawable, null);
+
+ doAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ Drawable drawable = (Drawable) invocation.getArguments()[0];
+ assertTrue(drawable instanceof SquaringDrawable);
+ return null;
+ }
+ }).when(mockView).setImageDrawable(any(Drawable.class));
+ verify(mockView).setImageDrawable(any(BitmapDrawable.class));
+ }
+
+ @Test
+ public void testDoesNotWrapInSquaringDrawableIfDrawableIsAnimated() {
+ ImageView mockView = mock(ImageView.class);
+ when(mockView.getWidth()).thenReturn(100);
+ when(mockView.getHeight()).thenReturn(100);
+ DrawableImageViewTarget target = new DrawableImageViewTarget(mockView);
+ Drawable drawable = new AnimationDrawable() {
+ @Override
+ public int getIntrinsicHeight() {
+ return 100;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return 100;
+ }
+ };
+ target.onResourceReady(drawable, null);
+
+ doAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ Drawable drawable = (Drawable) invocation.getArguments()[0];
+ assertFalse(drawable instanceof SquaringDrawable);
+ return null;
+ }
+ }).when(mockView).setImageDrawable(any(Drawable.class));
+ verify(mockView).setImageDrawable(any(BitmapDrawable.class));
+ }
+
+ @Test
+ public void testDoesNotWrapInSquaringDrawableIfDrawableIsNotSquare() {
+ ImageView mockView = mock(ImageView.class);
+ when(mockView.getWidth()).thenReturn(100);
+ when(mockView.getHeight()).thenReturn(100);
+ DrawableImageViewTarget target = new DrawableImageViewTarget(mockView);
+ Drawable drawable = new ColorDrawable(Color.RED) {
+ @Override
+ public int getIntrinsicHeight() {
+ return 100;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return 150;
+ }
+ };
+ target.onResourceReady(drawable, null);
+
+ doAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ Drawable drawable = (Drawable) invocation.getArguments()[0];
+ assertFalse(drawable instanceof SquaringDrawable);
+ return null;
+ }
+ }).when(mockView).setImageDrawable(any(Drawable.class));
+ verify(mockView).setImageDrawable(any(BitmapDrawable.class));
+ }
+
+ @Test
+ public void testDoesNotWrapInSquaringDrawableIfViewNotSquare() {
+ ImageView mockView = mock(ImageView.class);
+ when(mockView.getWidth()).thenReturn(100);
+ when(mockView.getHeight()).thenReturn(150);
+ DrawableImageViewTarget target = new DrawableImageViewTarget(mockView);
+ Drawable drawable = new ColorDrawable(Color.RED) {
+ @Override
+ public int getIntrinsicHeight() {
+ return 100;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return 100;
+ }
+ };
+ target.onResourceReady(drawable, null);
+
+ doAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ Drawable drawable = (Drawable) invocation.getArguments()[0];
+ assertFalse(drawable instanceof SquaringDrawable);
+ return null;
+ }
+ }).when(mockView).setImageDrawable(any(Drawable.class));
+ verify(mockView).setImageDrawable(any(BitmapDrawable.class));
+ }
+} \ No newline at end of file
diff --git a/library/src/test/java/com/bumptech/glide/request/target/ViewTargetTest.java b/library/src/test/java/com/bumptech/glide/request/target/ViewTargetTest.java
index 66832dc4..ecc0deda 100644
--- a/library/src/test/java/com/bumptech/glide/request/target/ViewTargetTest.java
+++ b/library/src/test/java/com/bumptech/glide/request/target/ViewTargetTest.java
@@ -242,6 +242,20 @@ public class ViewTargetTest {
verify(cb).onSizeReady(eq(width), eq(height));
}
+ @Test(expected = NullPointerException.class)
+ public void testThrowsIfGivenNullView() {
+ ViewTarget viewTarget = new ViewTarget(null) {
+ @Override
+ public void onResourceReady(Object resource, GlideAnimation glideAnimation) {
+
+ }
+
+ @Override
+ public void setPlaceholder(Drawable placeholder) {
+
+ }
+ };
+ }
@Implements(ViewTreeObserver.class)
public static class PreDrawShadowViewTreeObserver extends ShadowViewTreeObserver {