Skip to content

Commit 0b99260

Browse files
committed
Allow users to specify default transition options in GlideBuilder.
Fixes #2182.
1 parent 7e1548b commit 0b99260

File tree

8 files changed

+156
-21
lines changed

8 files changed

+156
-21
lines changed

library/src/main/java/com/bumptech/glide/Glide.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
import java.util.Collections;
8181
import java.util.Iterator;
8282
import java.util.List;
83+
import java.util.Map;
8384
import java.util.Set;
8485

8586
/**
@@ -275,7 +276,8 @@ private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules() {
275276
RequestManagerRetriever requestManagerRetriever,
276277
ConnectivityMonitorFactory connectivityMonitorFactory,
277278
int logLevel,
278-
RequestOptions defaultRequestOptions) {
279+
RequestOptions defaultRequestOptions,
280+
Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions) {
279281
this.engine = engine;
280282
this.bitmapPool = bitmapPool;
281283
this.arrayPool = arrayPool;
@@ -374,7 +376,8 @@ private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules() {
374376
ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
375377
glideContext =
376378
new GlideContext(
377-
context, registry, imageViewTargetFactory, defaultRequestOptions, engine, logLevel);
379+
context, registry, imageViewTargetFactory, defaultRequestOptions,
380+
defaultTransitionOptions, engine, logLevel);
378381
}
379382

380383
/**

library/src/main/java/com/bumptech/glide/GlideBuilder.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.bumptech.glide;
22

33
import android.content.Context;
4+
import android.support.annotation.NonNull;
45
import android.support.annotation.Nullable;
6+
import android.support.v4.util.ArrayMap;
57
import android.util.Log;
68
import com.bumptech.glide.load.DecodeFormat;
79
import com.bumptech.glide.load.engine.Engine;
@@ -20,11 +22,13 @@
2022
import com.bumptech.glide.manager.RequestManagerRetriever;
2123
import com.bumptech.glide.manager.RequestManagerRetriever.RequestManagerFactory;
2224
import com.bumptech.glide.request.RequestOptions;
25+
import java.util.Map;
2326

2427
/**
2528
* A builder class for setting default structural classes for Glide to use.
2629
*/
2730
public final class GlideBuilder {
31+
private final Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions = new ArrayMap<>();
2832
private Engine engine;
2933
private BitmapPool bitmapPool;
3034
private ArrayPool arrayPool;
@@ -157,6 +161,28 @@ public GlideBuilder setDefaultRequestOptions(RequestOptions requestOptions) {
157161
return this;
158162
}
159163

164+
/**
165+
* Sets the default {@link TransitionOptions} to use when starting a request that will load a
166+
* resource with the given {@link Class}.
167+
*
168+
* <p>It's preferable but not required for the requested resource class to match the resource
169+
* class applied here as long as the resource class applied here is assignable from the requested
170+
* resource class. For example you can set a default transition for
171+
* {@link android.graphics.drawable.Drawable} and that default transition will be used if you
172+
* subsequently start requests for specific {@link android.graphics.drawable.Drawable} types like
173+
* {@link com.bumptech.glide.load.resource.gif.GifDrawable} or
174+
* {@link android.graphics.drawable.BitmapDrawable}. Specific types are always preferred so if you
175+
* register a default transition for both {@link android.graphics.drawable.Drawable} and
176+
* {@link android.graphics.drawable.BitmapDrawable} and then start a request for
177+
* {@link android.graphics.drawable.BitmapDrawable}s, the transition you registered for
178+
* {@link android.graphics.drawable.BitmapDrawable}s will be used.
179+
*/
180+
public <T> GlideBuilder setDefaultTransitionOptions(
181+
@NonNull Class<T> clazz, @Nullable TransitionOptions<?, T> options) {
182+
defaultTransitionOptions.put(clazz, options);
183+
return this;
184+
}
185+
160186
/**
161187
* Sets the {@link com.bumptech.glide.load.DecodeFormat} that will be the default format for all
162188
* the default decoders that can change the {@link android.graphics.Bitmap.Config} of the {@link
@@ -314,6 +340,7 @@ public Glide build(Context context) {
314340
requestManagerRetriever,
315341
connectivityMonitorFactory,
316342
logLevel,
317-
defaultRequestOptions.lock());
343+
defaultRequestOptions.lock(),
344+
defaultTransitionOptions);
318345
}
319346
}

library/src/main/java/com/bumptech/glide/GlideContext.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,42 @@
66
import android.os.Build;
77
import android.os.Handler;
88
import android.os.Looper;
9+
import android.support.annotation.NonNull;
10+
import android.support.annotation.VisibleForTesting;
911
import android.widget.ImageView;
1012
import com.bumptech.glide.load.engine.Engine;
1113
import com.bumptech.glide.request.RequestOptions;
1214
import com.bumptech.glide.request.target.ImageViewTargetFactory;
1315
import com.bumptech.glide.request.target.Target;
16+
import java.util.Map;
17+
import java.util.Map.Entry;
1418

1519
/**
1620
* Global context for all loads in Glide containing and exposing the various registries and classes
1721
* required to load resources.
1822
*/
1923
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
2024
public class GlideContext extends ContextWrapper {
25+
@VisibleForTesting
26+
static final TransitionOptions<?, ?> DEFAULT_TRANSITION_OPTIONS =
27+
new GenericTransitionOptions<Object>();
2128
private final Handler mainHandler;
2229
private final Registry registry;
2330
private final ImageViewTargetFactory imageViewTargetFactory;
2431
private final RequestOptions defaultRequestOptions;
32+
private final Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions;
2533
private final Engine engine;
2634
private final int logLevel;
2735

2836
public GlideContext(Context context, Registry registry,
2937
ImageViewTargetFactory imageViewTargetFactory, RequestOptions defaultRequestOptions,
30-
Engine engine, int logLevel) {
38+
Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions, Engine engine,
39+
int logLevel) {
3140
super(context.getApplicationContext());
3241
this.registry = registry;
3342
this.imageViewTargetFactory = imageViewTargetFactory;
3443
this.defaultRequestOptions = defaultRequestOptions;
44+
this.defaultTransitionOptions = defaultTransitionOptions;
3545
this.engine = engine;
3646
this.logLevel = logLevel;
3747

@@ -42,6 +52,23 @@ public RequestOptions getDefaultRequestOptions() {
4252
return defaultRequestOptions;
4353
}
4454

55+
@SuppressWarnings("unchecked")
56+
@NonNull
57+
public <T> TransitionOptions<?, T> getDefaultTransitionOptions(Class<T> transcodeClass) {
58+
TransitionOptions<?, ?> result = defaultTransitionOptions.get(transcodeClass);
59+
if (result == null) {
60+
for (Entry<Class<?>, TransitionOptions<?, ?>> value : defaultTransitionOptions.entrySet()) {
61+
if (value.getKey().isAssignableFrom(transcodeClass)) {
62+
result = value.getValue();
63+
}
64+
}
65+
}
66+
if (result == null) {
67+
result = DEFAULT_TRANSITION_OPTIONS;
68+
}
69+
return (TransitionOptions<?, T>) result;
70+
}
71+
4572
public <X> Target<X> buildImageViewTarget(ImageView imageView, Class<X> transcodeClass) {
4673
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
4774
}

library/src/main/java/com/bumptech/glide/RequestBuilder.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
* {@link com.bumptech.glide.request.target.Target}.
3333
*/
3434
public class RequestBuilder<TranscodeType> implements Cloneable {
35-
private static final TransitionOptions<?, ?> DEFAULT_ANIMATION_OPTIONS =
36-
new GenericTransitionOptions<Object>();
3735
// Used in generated subclasses
3836
protected static final RequestOptions DOWNLOAD_ONLY_OPTIONS =
3937
new RequestOptions().diskCacheStrategy(DiskCacheStrategy.DATA).priority(Priority.LOW)
@@ -46,16 +44,18 @@ public class RequestBuilder<TranscodeType> implements Cloneable {
4644
private final Glide glide;
4745

4846
@NonNull protected RequestOptions requestOptions;
47+
48+
@NonNull
4949
@SuppressWarnings("unchecked")
50-
private TransitionOptions<?, ? super TranscodeType> transitionOptions =
51-
(TransitionOptions<?, ? super TranscodeType>) DEFAULT_ANIMATION_OPTIONS;
50+
private TransitionOptions<?, ? super TranscodeType> transitionOptions;
5251

5352
@Nullable private Object model;
5453
// model may occasionally be null, so to enforce that load() was called, put a boolean rather
5554
// than relying on model not to be null.
5655
@Nullable private RequestListener<TranscodeType> requestListener;
5756
@Nullable private RequestBuilder<TranscodeType> thumbnailBuilder;
5857
@Nullable private Float thumbSizeMultiplier;
58+
private boolean isDefaultTransitionOptionsSet = true;
5959
private boolean isModelSet;
6060
private boolean isThumbnailBuilt;
6161

@@ -66,6 +66,7 @@ protected RequestBuilder(Glide glide, RequestManager requestManager,
6666
this.context = glide.getGlideContext();
6767
this.transcodeClass = transcodeClass;
6868
this.defaultRequestOptions = requestManager.getDefaultRequestOptions();
69+
this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
6970
this.requestOptions = defaultRequestOptions;
7071
}
7172

@@ -106,6 +107,7 @@ protected RequestOptions getMutableOptions() {
106107
public RequestBuilder<TranscodeType> transition(
107108
@NonNull TransitionOptions<?, ? super TranscodeType> transitionOptions) {
108109
this.transitionOptions = Preconditions.checkNotNull(transitionOptions);
110+
isDefaultTransitionOptionsSet = false;
109111
return this;
110112
}
111113

@@ -589,7 +591,10 @@ private Request buildRequestRecursive(Target<TranscodeType> target,
589591

590592
TransitionOptions<?, ? super TranscodeType> thumbTransitionOptions =
591593
thumbnailBuilder.transitionOptions;
592-
if (DEFAULT_ANIMATION_OPTIONS.equals(thumbTransitionOptions)) {
594+
595+
// Apply our transition by default to thumbnail requests but avoid overriding custom options
596+
// that may have been applied on the thumbnail request explicitly.
597+
if (thumbnailBuilder.isDefaultTransitionOptionsSet) {
593598
thumbTransitionOptions = transitionOptions;
594599
}
595600

library/src/main/java/com/bumptech/glide/RequestManager.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import android.support.annotation.Nullable;
1414
import android.view.View;
1515
import com.bumptech.glide.load.engine.DiskCacheStrategy;
16-
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
1716
import com.bumptech.glide.load.resource.gif.GifDrawable;
1817
import com.bumptech.glide.manager.ConnectivityMonitor;
1918
import com.bumptech.glide.manager.ConnectivityMonitorFactory;
@@ -294,8 +293,7 @@ public void onDestroy() {
294293
* @return A new request builder for loading a {@link android.graphics.Bitmap}
295294
*/
296295
public RequestBuilder<Bitmap> asBitmap() {
297-
return as(Bitmap.class).transition(new GenericTransitionOptions<Bitmap>())
298-
.apply(DECODE_TYPE_BITMAP);
296+
return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
299297
}
300298

301299
/**
@@ -312,7 +310,7 @@ public RequestBuilder<Bitmap> asBitmap() {
312310
* {@link com.bumptech.glide.load.resource.gif.GifDrawable}.
313311
*/
314312
public RequestBuilder<GifDrawable> asGif() {
315-
return as(GifDrawable.class).transition(new DrawableTransitionOptions()).apply(DECODE_TYPE_GIF);
313+
return as(GifDrawable.class).apply(DECODE_TYPE_GIF);
316314
}
317315

318316
/**
@@ -326,7 +324,7 @@ public RequestBuilder<GifDrawable> asGif() {
326324
* @return A new request builder for loading a {@link Drawable}.
327325
*/
328326
public RequestBuilder<Drawable> asDrawable() {
329-
return as(Drawable.class).transition(new DrawableTransitionOptions());
327+
return as(Drawable.class);
330328
}
331329

332330
/**
@@ -460,6 +458,11 @@ RequestOptions getDefaultRequestOptions() {
460458
return requestOptions;
461459
}
462460

461+
@NonNull
462+
<T> TransitionOptions<?, T> getDefaultTransitionOptions(Class<T> transcodeClass) {
463+
return glide.getGlideContext().getDefaultTransitionOptions(transcodeClass);
464+
}
465+
463466
@Override
464467
public String toString() {
465468
return super.toString() + "{tracker=" + requestTracker + ", treeNode=" + treeNode + "}";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.bumptech.glide;
2+
3+
import static com.google.common.truth.Truth.assertThat;
4+
import static org.mockito.Mockito.mock;
5+
6+
import android.app.Application;
7+
import android.graphics.Bitmap;
8+
import android.graphics.drawable.BitmapDrawable;
9+
import android.graphics.drawable.Drawable;
10+
import android.util.Log;
11+
import com.bumptech.glide.load.engine.Engine;
12+
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
13+
import com.bumptech.glide.load.resource.gif.GifDrawable;
14+
import com.bumptech.glide.request.RequestOptions;
15+
import com.bumptech.glide.request.target.ImageViewTargetFactory;
16+
import java.util.HashMap;
17+
import java.util.Map;
18+
import org.junit.Before;
19+
import org.junit.Test;
20+
import org.junit.runner.RunWith;
21+
import org.robolectric.RobolectricTestRunner;
22+
import org.robolectric.RuntimeEnvironment;
23+
import org.robolectric.annotation.Config;
24+
25+
@RunWith(RobolectricTestRunner.class)
26+
@Config(manifest = Config.NONE)
27+
public final class GlideContextTest {
28+
private Map<Class<?>, TransitionOptions<?, ?>> transitionOptions;
29+
private GlideContext context;
30+
31+
@Before
32+
public void setUp() {
33+
Application app = RuntimeEnvironment.application;
34+
35+
transitionOptions = new HashMap<>();
36+
context = new GlideContext(app, new Registry(),
37+
new ImageViewTargetFactory(), new RequestOptions(),
38+
transitionOptions, mock(Engine.class), Log.DEBUG);
39+
}
40+
41+
@Test
42+
public void getDefaultTransitionOptions_withNoOptionsRegistered_returnsDefaultOptions() {
43+
assertThat(context.getDefaultTransitionOptions(Object.class))
44+
.isEqualTo(GlideContext.DEFAULT_TRANSITION_OPTIONS);
45+
}
46+
47+
@Test
48+
public void getDefaultTransitionOptions_withNonMatchingOptionRegistered_returnsDefaultOptions() {
49+
transitionOptions.put(Bitmap.class, new GenericTransitionOptions<>());
50+
assertThat(context.getDefaultTransitionOptions(Drawable.class))
51+
.isEqualTo(GlideContext.DEFAULT_TRANSITION_OPTIONS);
52+
}
53+
54+
@Test
55+
public void getDefaultTransitionOptions_withMatchingOptionsRegistered_returnsMatchingOptions() {
56+
GenericTransitionOptions<Object> expected = new GenericTransitionOptions<>();
57+
transitionOptions.put(Bitmap.class, expected);
58+
assertThat(context.getDefaultTransitionOptions(Bitmap.class))
59+
.isEqualTo(expected);
60+
}
61+
62+
@Test
63+
public void getDefaultTransitionOptions_withSuperClassRegistered_returnsSuperClassOptions() {
64+
DrawableTransitionOptions expected = new DrawableTransitionOptions();
65+
transitionOptions.put(Drawable.class, expected);
66+
assertThat(context.getDefaultTransitionOptions(BitmapDrawable.class))
67+
.isEqualTo(expected);
68+
assertThat(context.getDefaultTransitionOptions(GifDrawable.class))
69+
.isEqualTo(expected);
70+
}
71+
}

library/src/test/java/com/bumptech/glide/RequestBuilderTest.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.bumptech.glide;
22

33
import static com.bumptech.glide.tests.BackgroundUtil.testInBackground;
4+
import static org.mockito.Matchers.any;
45
import static org.mockito.Matchers.eq;
56
import static org.mockito.Matchers.isA;
67
import static org.mockito.Mockito.mock;
@@ -115,7 +116,9 @@ private RequestBuilder<Object> getNullModelRequest() {
115116
.thenReturn(mock(Target.class));
116117
when(glideContext.getDefaultRequestOptions()).thenReturn(new RequestOptions());
117118
when(requestManager.getDefaultRequestOptions())
118-
.thenReturn((RequestOptions) new RequestOptions());
119+
.thenReturn(new RequestOptions());
120+
when(requestManager.getDefaultTransitionOptions(any(Class.class)))
121+
.thenReturn(new GenericTransitionOptions<>());
119122
return new RequestBuilder<>(glide, requestManager, Object.class)
120123
.load((Object) null);
121124
}

samples/flickr/src/main/java/com/bumptech/glide/samples/flickr/FlickrPhotoGrid.java

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.bumptech.glide.samples.flickr;
22

3-
import static com.bumptech.glide.GenericTransitionOptions.withNoTransition;
4-
53
import android.content.Intent;
64
import android.graphics.Rect;
75
import android.graphics.drawable.Drawable;
@@ -65,15 +63,13 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
6563

6664
fullRequest = GlideApp.with(this)
6765
.asDrawable()
68-
.centerCrop()
69-
.transition(withNoTransition());
66+
.centerCrop();
7067

7168
thumbnailRequest = GlideApp.with(this)
7269
.asDrawable()
7370
.diskCacheStrategy(DiskCacheStrategy.DATA)
7471
.centerCrop()
75-
.override(Api.SQUARE_THUMB_SIZE)
76-
.transition(withNoTransition());
72+
.override(Api.SQUARE_THUMB_SIZE);
7773

7874
preloadRequest =
7975
thumbnail ? thumbnailRequest.clone().priority(Priority.HIGH) : fullRequest;

0 commit comments

Comments
 (0)