aboutsummaryrefslogtreecommitdiff
path: root/library/src/main/java/com/bumptech
diff options
context:
space:
mode:
authorSam Judd <judds@google.com>2014-09-23 07:14:03 -0700
committerSam Judd <judds@google.com>2014-09-24 18:33:47 -0700
commitf2285a83d5ac3e79383278b91aa21b0a87603cd1 (patch)
tree67d8e576b9e6acf266ea55a975e142e94a17bff5 /library/src/main/java/com/bumptech
parente7812093bde705833531b43be2e9dc92adef1f5d (diff)
downloadglide-f2285a83d5ac3e79383278b91aa21b0a87603cd1.tar.gz
Add support for recursive thumbnail calls.
Fixes #149
Diffstat (limited to 'library/src/main/java/com/bumptech')
-rw-r--r--library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java86
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/SourceResourceRunner.java7
-rw-r--r--library/src/main/java/com/bumptech/glide/request/GenericRequest.java13
-rw-r--r--library/src/main/java/com/bumptech/glide/request/Request.java6
-rw-r--r--library/src/main/java/com/bumptech/glide/request/RequestCoordinator.java2
-rw-r--r--library/src/main/java/com/bumptech/glide/request/ThumbnailRequestCoordinator.java43
-rw-r--r--library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java10
7 files changed, 99 insertions, 68 deletions
diff --git a/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java b/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
index 405336bb..5da47ab6 100644
--- a/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
+++ b/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
@@ -54,7 +54,8 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
private final Class<TranscodeType> transcodeClass;
private final Glide glide;
private final RequestTracker requestTracker;
- private Lifecycle lifecycle;
+ private final Lifecycle lifecycle;
+
private int placeholderId;
private int errorId;
private RequestListener<ModelType, TranscodeType> requestListener;
@@ -94,21 +95,14 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
/**
* Loads and displays the resource retrieved by the given thumbnail request if it finishes before this request.
- * Best used for loading thumbnail resources that are smaller and will be loaded more quickly than the fullsize
+ * Best used for loading thumbnail resources that are smaller and will be loaded more quickly than the full size
* resource. There are no guarantees about the order in which the requests will actually finish. However, if the
* thumb request completes after the full request, the thumb resource will never replace the full resource.
*
* @see #thumbnail(float)
*
* <p>
- * Note - Any options on the main request will not be passed on to the thumbnail request. For example, if
- * you want an animation to occur when either the full resource loads or the thumbnail loads, you need to call
- * {@link #animate(int)} on both the thumb and the full request. For a simpler thumbnail option, see
- * {@link #thumbnail(float)}.
- * </p>
- *
- * <p>
- * Only the thumbnail call on the main request will be obeyed.
+ * Recursive calls to thumbnail are supported.
* </p>
*
* @param thumbnailRequest The request to use to load the thumbnail.
@@ -141,7 +135,7 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
* </p>
*
* <p>
- * Only the thumbnail call on the main request will be obeyed.
+ * Recursive calls to thumbnail are supported.
* </p>
*
* @param sizeMultiplier The multiplier to apply to the {@link Target}'s dimensions when loading the thumbnail.
@@ -613,17 +607,28 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
// To be implemented by subclasses when possible.
}
- private Request buildRequest(Target<TranscodeType> target) {
- final Request result;
+ private Priority getThumbnailPriority() {
+ final Priority result;
+ if (priority == Priority.LOW) {
+ result = Priority.NORMAL;
+ } else if (priority == Priority.NORMAL) {
+ result = Priority.HIGH;
+ } else {
+ result = Priority.IMMEDIATE;
+ }
+ return result;
+ }
+ private Request buildRequest(Target<TranscodeType> target) {
if (priority == null) {
priority = Priority.NORMAL;
}
+ return buildRequestRecursive(target, null);
+ }
+ private Request buildRequestRecursive(Target<TranscodeType> target, ThumbnailRequestCoordinator parentCoordinator) {
if (thumbnailRequestBuilder != null) {
- ThumbnailRequestCoordinator requestCoordinator = new ThumbnailRequestCoordinator();
- Request fullRequest = buildRequest(target, sizeMultiplier, priority, requestCoordinator);
-
+ // Recursive case: contains a potentially recursive thumbnail request builder.
if (thumbnailRequestBuilder.animationFactory.equals(NoAnimation.getFactory())) {
thumbnailRequestBuilder.animationFactory = animationFactory;
}
@@ -636,48 +641,31 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
thumbnailRequestBuilder.priority = getThumbnailPriority();
}
- Request thumbnailRequest = thumbnailRequestBuilder.buildRequest(target,
- thumbnailRequestBuilder.sizeMultiplier, thumbnailRequestBuilder.priority, requestCoordinator);
-
- requestCoordinator.setRequests(fullRequest, thumbnailRequest);
- result = requestCoordinator;
+ ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
+ Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
+ // Recursively generate thumbnail requests.
+ Request thumbRequest = thumbnailRequestBuilder.buildRequestRecursive(target, coordinator);
+ coordinator.setRequests(fullRequest, thumbRequest);
+ return coordinator;
} else if (thumbSizeMultiplier != null) {
- ThumbnailRequestCoordinator requestCoordinator = new ThumbnailRequestCoordinator();
- Request fullRequest = buildRequest(target, sizeMultiplier, priority, requestCoordinator);
- Request thumbnailRequest = buildRequest(target, thumbSizeMultiplier, getThumbnailPriority(),
- requestCoordinator);
- requestCoordinator.setRequests(fullRequest, thumbnailRequest);
- result = requestCoordinator;
+ // Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
+ ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
+ Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
+ Request thumbnailRequest = obtainRequest(target, thumbSizeMultiplier, getThumbnailPriority(), coordinator);
+ coordinator.setRequests(fullRequest, thumbnailRequest);
+ return coordinator;
} else {
- result = buildRequest(target, sizeMultiplier, priority, null);
+ // Base case: no thumbnail.
+ return obtainRequest(target, sizeMultiplier, priority, parentCoordinator);
}
- return result;
}
- private Priority getThumbnailPriority() {
- final Priority result;
- if (priority == Priority.LOW) {
- result = Priority.NORMAL;
- } else if (priority == Priority.NORMAL) {
- result = Priority.HIGH;
- } else {
- result = Priority.IMMEDIATE;
- }
- return result;
- }
-
- private Request buildRequest(Target<TranscodeType> target, float sizeMultiplier, Priority priority,
+ private <Z> Request obtainRequest(Target<TranscodeType> target, float sizeMultiplier, Priority priority,
RequestCoordinator requestCoordinator) {
if (model == null) {
- return buildRequestForDataType(target, loadProvider, sizeMultiplier, priority, null);
- } else {
- return buildRequestForDataType(target, loadProvider, sizeMultiplier, priority, requestCoordinator);
+ requestCoordinator = null;
}
- }
- private <Z> Request buildRequestForDataType(Target<TranscodeType> target,
- LoadProvider<ModelType, Z, ResourceType, TranscodeType> loadProvider, float sizeMultiplier,
- Priority priority, RequestCoordinator requestCoordinator) {
return GenericRequest.obtain(
loadProvider,
model,
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/SourceResourceRunner.java b/library/src/main/java/com/bumptech/glide/load/engine/SourceResourceRunner.java
index acf38865..2dd3ff1e 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/SourceResourceRunner.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/SourceResourceRunner.java
@@ -143,7 +143,8 @@ class SourceResourceRunner<T, Z, R> implements Runnable, Prioritized {
if (decoded == null) {
decoded = decodeFromSource();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Decoded from source in " + (SystemClock.currentThreadTimeMillis() - start) + " cache");
+ Log.v(TAG, "Decoded from source in " + (SystemClock.currentThreadTimeMillis() - start) + " key: "
+ + key);
start = SystemClock.currentThreadTimeMillis();
}
}
@@ -155,7 +156,7 @@ class SourceResourceRunner<T, Z, R> implements Runnable, Prioritized {
decoded.recycle();
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "transformed in " + (SystemClock.currentThreadTimeMillis() - start));
+ Log.v(TAG, "transformed in " + (SystemClock.currentThreadTimeMillis() - start) + " key: " + key);
}
}
@@ -167,7 +168,7 @@ class SourceResourceRunner<T, Z, R> implements Runnable, Prioritized {
start = SystemClock.currentThreadTimeMillis();
transcoded = transcoder.transcode(transformed);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.d(TAG, "transcoded in " + (SystemClock.currentThreadTimeMillis() - start));
+ Log.d(TAG, "transcoded in " + (SystemClock.currentThreadTimeMillis() - start) + " key: " + key);
}
}
return transcoded;
diff --git a/library/src/main/java/com/bumptech/glide/request/GenericRequest.java b/library/src/main/java/com/bumptech/glide/request/GenericRequest.java
index 999e464b..4f729421 100644
--- a/library/src/main/java/com/bumptech/glide/request/GenericRequest.java
+++ b/library/src/main/java/com/bumptech/glide/request/GenericRequest.java
@@ -338,6 +338,17 @@ public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallb
return status == Status.COMPLETE;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isResourceSet() {
+ return isComplete();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean isCancelled() {
return status == Status.CANCELLED;
@@ -428,7 +439,7 @@ public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallb
}
private boolean isFirstReadyResource() {
- return requestCoordinator == null || !requestCoordinator.isAnyRequestComplete();
+ return requestCoordinator == null || !requestCoordinator.isAnyResourceSet();
}
/**
diff --git a/library/src/main/java/com/bumptech/glide/request/Request.java b/library/src/main/java/com/bumptech/glide/request/Request.java
index b1c4e917..9dbf1d17 100644
--- a/library/src/main/java/com/bumptech/glide/request/Request.java
+++ b/library/src/main/java/com/bumptech/glide/request/Request.java
@@ -37,6 +37,12 @@ public interface Request {
public boolean isComplete();
/**
+ * Returns true if a non-placeholder resource is set. For Requests that load more than one resource, isResourceSet
+ * may return true even if {@link #isComplete()}} returns false.
+ */
+ public boolean isResourceSet();
+
+ /**
* Returns true if the request has been cancelled.
*/
public boolean isCancelled();
diff --git a/library/src/main/java/com/bumptech/glide/request/RequestCoordinator.java b/library/src/main/java/com/bumptech/glide/request/RequestCoordinator.java
index 0592559d..47b77daf 100644
--- a/library/src/main/java/com/bumptech/glide/request/RequestCoordinator.java
+++ b/library/src/main/java/com/bumptech/glide/request/RequestCoordinator.java
@@ -24,5 +24,5 @@ public interface RequestCoordinator {
*
* @see Request#isComplete()
*/
- public boolean isAnyRequestComplete();
+ public boolean isAnyResourceSet();
}
diff --git a/library/src/main/java/com/bumptech/glide/request/ThumbnailRequestCoordinator.java b/library/src/main/java/com/bumptech/glide/request/ThumbnailRequestCoordinator.java
index d7033e45..948c62a5 100644
--- a/library/src/main/java/com/bumptech/glide/request/ThumbnailRequestCoordinator.java
+++ b/library/src/main/java/com/bumptech/glide/request/ThumbnailRequestCoordinator.java
@@ -7,6 +7,15 @@ package com.bumptech.glide.request;
public class ThumbnailRequestCoordinator implements RequestCoordinator, Request {
private Request full;
private Request thumb;
+ private RequestCoordinator coordinator;
+
+ public ThumbnailRequestCoordinator() {
+ this(null);
+ }
+
+ public ThumbnailRequestCoordinator(RequestCoordinator coordinator) {
+ this.coordinator = coordinator;
+ }
public void setRequests(Request full, Request thumb) {
this.full = full;
@@ -14,14 +23,19 @@ public class ThumbnailRequestCoordinator implements RequestCoordinator, Request
}
/**
+ *
* Returns true if the request is either the request loading the fullsize image or if the request loading the
- * fullsize image has not yet completed.
+ * full size image has not yet completed.
*
* @param request {@inheritDoc}
*/
@Override
public boolean canSetImage(Request request) {
- return request == full || !full.isComplete();
+ return parentCanSetImage() && (request == full || !full.isResourceSet());
+ }
+
+ private boolean parentCanSetImage() {
+ return coordinator == null || coordinator.canSetImage(this);
}
/**
@@ -32,16 +46,20 @@ public class ThumbnailRequestCoordinator implements RequestCoordinator, Request
*/
@Override
public boolean canNotifyStatusChanged(Request request) {
- return request == full && !isAnyRequestComplete();
+ return parentCanNotifyStatusChanged() && (request == full && !isAnyResourceSet());
+ }
+
+ private boolean parentCanNotifyStatusChanged() {
+ return coordinator == null || coordinator.canNotifyStatusChanged(this);
}
- /**
- * Returns true if either the full request has completed successfully or the thumb request has completed
- * successfully.
- */
@Override
- public boolean isAnyRequestComplete() {
- return full.isComplete() || thumb.isComplete();
+ public boolean isAnyResourceSet() {
+ return parentIsAnyResourceSet() || isResourceSet();
+ }
+
+ private boolean parentIsAnyResourceSet() {
+ return coordinator != null && coordinator.isAnyResourceSet();
}
/**
@@ -90,7 +108,12 @@ public class ThumbnailRequestCoordinator implements RequestCoordinator, Request
*/
@Override
public boolean isComplete() {
- return full.isComplete();
+ return full.isComplete() || thumb.isComplete();
+ }
+
+ @Override
+ public boolean isResourceSet() {
+ return full.isResourceSet() || thumb.isResourceSet();
}
@Override
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 fb20e58a..1091786b 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
@@ -7,12 +7,11 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
-
import com.bumptech.glide.request.Request;
import java.lang.ref.WeakReference;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.List;
/**
* A base {@link Target} for loading {@link android.graphics.Bitmap}s into {@link View}s that provides default
@@ -112,7 +111,7 @@ public abstract class ViewTarget<T extends View, Z> extends BaseTarget<Z> {
private static class SizeDeterminer {
private final View view;
- private Set<SizeReadyCallback> cbs = new HashSet<SizeReadyCallback>();
+ private List<SizeReadyCallback> cbs = new ArrayList<SizeReadyCallback>();
private SizeDeterminerLayoutListener layoutListener;
public SizeDeterminer(View view) {
@@ -173,6 +172,9 @@ public abstract class ViewTarget<T extends View, Z> extends BaseTarget<Z> {
}
cb.onSizeReady(width, height);
} else {
+ if (cbs.contains(cb)) {
+ throw new IllegalArgumentException("Cannot add a callback twice");
+ }
cbs.add(cb);
final ViewTreeObserver observer = view.getViewTreeObserver();
layoutListener = new SizeDeterminerLayoutListener(this);