Skip to content

Commit

Permalink
Add a fallback Drawable to display for null models
Browse files Browse the repository at this point in the history
Fixes #268
  • Loading branch information
sjudd committed May 1, 2015
1 parent b9a2d3b commit 9548211
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ private static class RequestHarness {
int placeholderResourceId = 0;
Drawable placeholderDrawable = null;
int errorResourceId = 0;
Drawable fallbackDrawable = null;
int fallbackResourceId = 0;
Transformation transformation = mock(Transformation.class);
Drawable errorDrawable = null;
LoadProvider<Number, Object, Object, List> loadProvider = mock(LoadProvider.class);
Expand Down Expand Up @@ -122,6 +124,8 @@ public GenericRequest<Number, Object, Object, List> getRequest() {
placeholderResourceId,
errorDrawable,
errorResourceId,
fallbackDrawable,
fallbackResourceId,
requestListener,
requestCoordinator,
engine,
Expand Down Expand Up @@ -331,7 +335,8 @@ public void testCanHandleNullResources() {

assertTrue(request.isFailed());
verify(harness.requestListener)
.onException(any(Exception.class), any(Number.class), eq(harness.target), anyBoolean());
.onException(any(Exception.class), any(Number.class), eq(harness.target),
anyBoolean());
}

@Test
Expand All @@ -357,7 +362,8 @@ public void testCanHandleNonConformingResources() {
assertTrue(request.isFailed());
verify(harness.engine).release(eq(harness.resource));
verify(harness.requestListener)
.onException(any(Exception.class), any(Number.class), eq(harness.target), anyBoolean());
.onException(any(Exception.class), any(Number.class), eq(harness.target),
anyBoolean());
}

@Test
Expand Down Expand Up @@ -483,9 +489,10 @@ public void testIgnoresOnSizeReadyIfNotWaitingForSize() {
request.onSizeReady(100, 100);
request.onSizeReady(100, 100);

verify(harness.engine, times(1)).load(eq(harness.signature), eq(100), eq(100), any(DataFetcher.class),
any(DataLoadProvider.class), any(Transformation.class), any(ResourceTranscoder.class),
any(Priority.class), anyBoolean(), any(DiskCacheStrategy.class), any(ResourceCallback.class));
verify(harness.engine, times(1)).load(eq(harness.signature), eq(100), eq(100),
any(DataFetcher.class), any(DataLoadProvider.class), any(Transformation.class),
any(ResourceTranscoder.class), any(Priority.class), anyBoolean(),
any(DiskCacheStrategy.class), any(ResourceCallback.class));
}

@Test
Expand All @@ -506,8 +513,8 @@ public void testEngineLoadPassedCorrectPriority() {
request.onSizeReady(100, 100);

verify(harness.engine).load(any(Key.class), anyInt(), anyInt(), any(DataFetcher.class),
any(DataLoadProvider.class), any(Transformation.class), any(ResourceTranscoder.class),
eq(expected), anyBoolean(), any(DiskCacheStrategy.class), any(ResourceCallback.class));
any(DataLoadProvider.class), any(Transformation.class), any(ResourceTranscoder.class),
eq(expected), anyBoolean(), any(DiskCacheStrategy.class), any(ResourceCallback.class));
}

@Test
Expand Down Expand Up @@ -602,7 +609,7 @@ public void testErrorDrawableIsSetOnLoadFailed() {
}

@Test
public void setTestPlaceholderDrawableSetOnNullModel() {
public void testPlaceholderDrawableSetOnNullModelWithNoErrorDrawable() {
Drawable placeholder = new ColorDrawable(Color.RED);

MockTarget target = new MockTarget();
Expand All @@ -618,7 +625,7 @@ public void setTestPlaceholderDrawableSetOnNullModel() {
}

@Test
public void testErrorDrawableSetOnNullModel() {
public void testErrorDrawableSetOnNullModelWithErrorDrawable() {
Drawable placeholder = new ColorDrawable(Color.RED);
Drawable errorPlaceholder = new ColorDrawable(Color.GREEN);

Expand All @@ -635,6 +642,26 @@ public void testErrorDrawableSetOnNullModel() {
assertEquals(errorPlaceholder, target.currentPlaceholder);
}

@Test
public void testFallbackDrawableSetOnNullModelWithErrorAndFallbackDrawables() {
Drawable placeholder = new ColorDrawable(Color.RED);
Drawable errorPlaceholder = new ColorDrawable(Color.GREEN);
Drawable fallback = new ColorDrawable(Color.BLUE);

MockTarget target = new MockTarget();

harness.placeholderDrawable = placeholder;
harness.errorDrawable = errorPlaceholder;
harness.fallbackDrawable = fallback;
harness.target = target;
harness.model = null;
GenericRequest request = harness.getRequest();

request.begin();

assertEquals(fallback, target.currentPlaceholder);
}

@Test
public void testIsNotRunningBeforeRunCalled() {
assertFalse(harness.getRequest().isRunning());
Expand Down
12 changes: 12 additions & 0 deletions library/src/main/java/com/bumptech/glide/BitmapRequestBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,18 @@ public BitmapRequestBuilder<ModelType, TranscodeType> placeholder(Drawable drawa
return this;
}

@Override
public BitmapRequestBuilder<ModelType, TranscodeType> fallback(Drawable drawable) {
super.fallback(drawable);
return this;
}

@Override
public BitmapRequestBuilder<ModelType, TranscodeType> fallback(int resourceId) {
super.fallback(resourceId);
return this;
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,18 @@ public DrawableRequestBuilder<ModelType> placeholder(Drawable drawable) {
return this;
}

@Override
public DrawableRequestBuilder<ModelType> fallback(Drawable drawable) {
super.fallback(drawable);
return this;
}

@Override
public DrawableRequestBuilder<ModelType> fallback(int resourceId) {
super.fallback(resourceId);
return this;
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
private Transformation<ResourceType> transformation = UnitTransformation.get();
private boolean isTransformationSet;
private boolean isThumbnailBuilt;
private Drawable fallbackDrawable;
private int fallbackResource;

GenericRequestBuilder(LoadProvider<ModelType, DataType, ResourceType, TranscodeType> loadProvider,
Class<TranscodeType> transcodeClass, GenericRequestBuilder<ModelType, ?, ?, ?> other) {
Expand Down Expand Up @@ -447,6 +449,49 @@ public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> p
return this;
}

/**
* Sets an {@link android.graphics.drawable.Drawable} to display if the model provided to
* {@link #load(Object)} is {@code null}.
*
* <p>
* If a fallback is not set, null models will cause the error drawable to be displayed. If
* the error drawable is not set, the placeholder will be displayed.
* </p>
*
* @see #placeholder(Drawable)
* @see #placeholder(int)
*
* @param drawable The drawable to display as a placeholder.
* @return This request builder.
*/
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> fallback(
Drawable drawable) {
this.fallbackDrawable = drawable;

return this;
}

/**
* Sets a resource to display if the model provided to {@link #load(Object)} is {@code null}.
*
* <p>
* If a fallback is not set, null models will cause the error drawable to be displayed. If
* the error drawable is not set, the placeholder will be displayed.
* </p>
*
* @see #placeholder(Drawable)
* @see #placeholder(int)
*
* @param resourceId The id of the resource to use as a fallback.
* @return This request builder.
*/
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> fallback(
int resourceId) {
this.fallbackResource = resourceId;

return this;
}

/**
* Sets a resource to display if a load fails.
*
Expand Down Expand Up @@ -802,6 +847,8 @@ private Request obtainRequest(Target<TranscodeType> target, float sizeMultiplier
placeholderId,
errorPlaceholder,
errorId,
fallbackDrawable,
fallbackResource,
requestListener,
requestCoordinator,
glide.getEngine(),
Expand Down
12 changes: 12 additions & 0 deletions library/src/main/java/com/bumptech/glide/GifRequestBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,18 @@ public GifRequestBuilder<ModelType> placeholder(Drawable drawable) {
return this;
}

@Override
public GifRequestBuilder<ModelType> fallback(Drawable drawable) {
super.fallback(drawable);
return this;
}

@Override
public GifRequestBuilder<ModelType> fallback(int resourceId) {
super.fallback(resourceId);
return this;
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ private enum Status {
private final String tag = String.valueOf(hashCode());

private Key signature;
private Drawable fallbackDrawable;
private int fallbackResourceId;
private int placeholderResourceId;
private int errorResourceId;
private Context context;
Expand Down Expand Up @@ -99,6 +101,8 @@ public static <A, T, Z, R> GenericRequest<A, T, Z, R> obtain(
int placeholderResourceId,
Drawable errorDrawable,
int errorResourceId,
Drawable fallbackDrawable,
int fallbackResourceId,
RequestListener<? super A, R> requestListener,
RequestCoordinator requestCoordinator,
Engine engine,
Expand All @@ -125,6 +129,8 @@ public static <A, T, Z, R> GenericRequest<A, T, Z, R> obtain(
placeholderResourceId,
errorDrawable,
errorResourceId,
fallbackDrawable,
fallbackResourceId,
requestListener,
requestCoordinator,
engine,
Expand All @@ -150,6 +156,7 @@ public void recycle() {
target = null;
placeholderDrawable = null;
errorDrawable = null;
fallbackDrawable = null;
requestListener = null;
requestCoordinator = null;
transformation = null;
Expand All @@ -171,6 +178,8 @@ private void init(
int placeholderResourceId,
Drawable errorDrawable,
int errorResourceId,
Drawable fallbackDrawable,
int fallbackResourceId,
RequestListener<? super A, R> requestListener,
RequestCoordinator requestCoordinator,
Engine engine,
Expand All @@ -184,6 +193,8 @@ private void init(
this.loadProvider = loadProvider;
this.model = model;
this.signature = signature;
this.fallbackDrawable = fallbackDrawable;
this.fallbackResourceId = fallbackResourceId;
this.context = context.getApplicationContext();
this.priority = priority;
this.target = target;
Expand Down Expand Up @@ -371,12 +382,22 @@ public boolean isFailed() {
return status == Status.FAILED;
}

private Drawable getFallbackDrawable() {
if (fallbackDrawable == null && fallbackResourceId > 0) {
fallbackDrawable = context.getResources().getDrawable(fallbackResourceId);
}
return fallbackDrawable;
}

private void setErrorPlaceholder(Exception e) {
if (!canNotifyStatusChanged()) {
return;
}

Drawable error = getErrorDrawable();
Drawable error = model == null ? getFallbackDrawable() : null;
if (error == null) {
error = getErrorDrawable();
}
if (error == null) {
error = getPlaceholderDrawable();
}
Expand Down

0 comments on commit 9548211

Please sign in to comment.