1b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Juddpackage com.bumptech.glide;
2b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
3b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Juddimport android.content.Context;
4a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Juddimport android.graphics.drawable.Drawable;
5785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Juddimport android.view.View;
6531667420f0cb59e01e0ae5928392469006148ddSam Juddimport android.view.ViewPropertyAnimator;
7a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Juddimport android.view.animation.Animation;
8b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Juddimport android.widget.ImageView;
9cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Juddimport com.bumptech.glide.load.Encoder;
109bebdf4ee5dcaa1569bea3985dfe08f93ed8bd38Sam Juddimport com.bumptech.glide.load.MultiTransformation;
119fc12334a7d14347cd6951d0653264b2597bd3a0Sam Juddimport com.bumptech.glide.load.ResourceDecoder;
12d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Juddimport com.bumptech.glide.load.ResourceEncoder;
1380b7691daac313059e4311214249fa6da53451edSam Juddimport com.bumptech.glide.load.SkipCache;
149bebdf4ee5dcaa1569bea3985dfe08f93ed8bd38Sam Juddimport com.bumptech.glide.load.Transformation;
15ee914288218f2fa29a96ed746c9bd9995857c8cdSam Juddimport com.bumptech.glide.load.UnitTransformation;
167260e7b8e840ae9e03cc20df73accfc4121cb190Sam Juddimport com.bumptech.glide.load.model.ModelLoader;
17cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Juddimport com.bumptech.glide.load.model.NullEncoder;
18bcf4a0dae04a4ad14287eeb34069a97c96fe9bb1Sam Juddimport com.bumptech.glide.load.resource.bitmap.BitmapDecoder;
19bcf4a0dae04a4ad14287eeb34069a97c96fe9bb1Sam Juddimport com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
20667fb8129df68fbab0c489b23b2ca9d392cd45a0Sam Juddimport com.bumptech.glide.manager.RequestTracker;
219bebdf4ee5dcaa1569bea3985dfe08f93ed8bd38Sam Juddimport com.bumptech.glide.provider.ChildLoadProvider;
229fc12334a7d14347cd6951d0653264b2597bd3a0Sam Juddimport com.bumptech.glide.provider.LoadProvider;
23531667420f0cb59e01e0ae5928392469006148ddSam Juddimport com.bumptech.glide.request.GenericRequest;
24531667420f0cb59e01e0ae5928392469006148ddSam Juddimport com.bumptech.glide.request.GlideAnimationFactory;
25531667420f0cb59e01e0ae5928392469006148ddSam Juddimport com.bumptech.glide.request.NoAnimation;
26785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Juddimport com.bumptech.glide.request.Request;
279fc12334a7d14347cd6951d0653264b2597bd3a0Sam Juddimport com.bumptech.glide.request.RequestCoordinator;
281a0d2f25951a536b465c5b2a1dfa5d3c076de912Sam Juddimport com.bumptech.glide.request.RequestListener;
29531667420f0cb59e01e0ae5928392469006148ddSam Juddimport com.bumptech.glide.request.ThumbnailRequestCoordinator;
30531667420f0cb59e01e0ae5928392469006148ddSam Juddimport com.bumptech.glide.request.ViewAnimation;
31531667420f0cb59e01e0ae5928392469006148ddSam Juddimport com.bumptech.glide.request.ViewPropertyAnimation;
32785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Juddimport com.bumptech.glide.request.target.BitmapImageViewTarget;
339fc12334a7d14347cd6951d0653264b2597bd3a0Sam Juddimport com.bumptech.glide.request.target.Target;
34b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
35d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Juddimport java.io.InputStream;
36b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Juddimport java.util.ArrayList;
37b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Juddimport java.util.List;
38b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
39b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd/**
40b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd * A generic class that can handle loading a bitmap either from an image or as a thumbnail from a video given
41b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd * models loaders to translate a model into generic resources for either an image or a video and decoders that can
42b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd * decode those resources into bitmaps.
43b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd *
44b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd * @param  The type of model representing the image or video.
45dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd * @param  The data type that the image {@link ModelLoader} will provide that can be decoded by the image
4644e0516ee31912216c9e668c255f2d5baf86ac6dSam Judd *      {@link BitmapDecoder}.
4744e0516ee31912216c9e668c255f2d5baf86ac6dSam Judd * @param  The type of the resource that will be loaded.
48b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd */
49dbb67f826b0e76645c809be6d589e9dcb8271324Sam Juddpublic class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> {
50d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd    private final Context context;
51b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    private final ModelType model;
52dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    private final ChildLoadProvider<ModelType, DataType, ResourceType, TranscodeType> loadProvider;
5377e0200ba76c89177b6ec8c781f4f8f86984989bSam Judd    private final Class<TranscodeType> transcodeClass;
547260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd    private final Glide glide;
55667fb8129df68fbab0c489b23b2ca9d392cd45a0Sam Judd    private final RequestTracker requestTracker;
56cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd    private List<Transformation<ResourceType>> transformations = null;
57cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd    private Transformation<ResourceType> singleTransformation = UnitTransformation.get();
58b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    private int placeholderId;
59b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    private int errorId;
60444371118bf079a412017948166cf4eb4db48103Sam Judd    private RequestListener<ModelType, TranscodeType> requestListener;
61b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    private Float thumbSizeMultiplier;
62dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    private GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType>
63ad7119b91370d7418b24f5646b35190aa76e5e66Sam Judd            thumbnailRequestBuilder;
64b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    private Float sizeMultiplier = 1f;
65a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd    private Drawable placeholderDrawable;
66a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd    private Drawable errorPlaceholder;
6708b61677e60069ba681b56cf6312fc0b92020962Sam Judd    private Priority priority = null;
6880b7691daac313059e4311214249fa6da53451edSam Judd    private boolean isCacheable = true;
6980b7691daac313059e4311214249fa6da53451edSam Judd    private ResourceEncoder<ResourceType> preSkipEncoder;
70531667420f0cb59e01e0ae5928392469006148ddSam Judd    private GlideAnimationFactory<TranscodeType> animationFactory = NoAnimation.getFactory();
71b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd    private int overrideHeight = -1;
72b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd    private int overrideWidth = -1;
73cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd    private boolean cacheSource = false;
74cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd    private Encoder<DataType> preSkipSourceEncoder;
75b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
767260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd    GenericRequestBuilder(Context context, ModelType model,
77dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd            LoadProvider<ModelType, DataType, ResourceType, TranscodeType> loadProvider,
78667fb8129df68fbab0c489b23b2ca9d392cd45a0Sam Judd            Class<TranscodeType> transcodeClass, Glide glide, RequestTracker requestTracker) {
7977e0200ba76c89177b6ec8c781f4f8f86984989bSam Judd        this.transcodeClass = transcodeClass;
80d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd        this.glide = glide;
81667fb8129df68fbab0c489b23b2ca9d392cd45a0Sam Judd        this.requestTracker = requestTracker;
82dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd        this.loadProvider = loadProvider != null ?
83dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd                new ChildLoadProvider<ModelType, DataType, ResourceType, TranscodeType>(loadProvider) : null;
8480b7691daac313059e4311214249fa6da53451edSam Judd        preSkipEncoder = loadProvider != null ? loadProvider.getEncoder() : null;
85c8c79d03924a757c29bbe7df5bc07b3cf8e02a83Sam Judd
8627eb05702fd4531d6974640c62df1d569629edb6Sam Judd        if (context == null) {
87b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd            throw new NullPointerException("Context can't be null");
88b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        }
89dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd        if (model != null && loadProvider == null) {
90dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd            throw new NullPointerException("LoadProvider must not be null");
91b215b51a0ba86c2db14bd735cc0207cf3f1c7cd8Sam Judd        }
92c8c79d03924a757c29bbe7df5bc07b3cf8e02a83Sam Judd        this.context = context;
93b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        this.model = model;
94b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
95b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
96b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
97b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * Loads and displays the image retrieved by the given thumbnail request if it finishes before this request.
98b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * Best used for loading thumbnail images that are smaller and will be loaded more quickly than the fullsize
99b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * image. There are no guarantees about the order in which the requests will actually finish. However, if the
100b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * thumb request completes after the full request, the thumb image will never replace the full image.
101b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
102b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @see #thumbnail(float)
103b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
104b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * <p>
105b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     Note - Any options on the main request will not be passed on to the thumbnail request. For example, if
106b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     you want an animation to occur when either the full image loads or the thumbnail loads, you need to call
107b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     {@link #animate(int)} on both the thumb and the full request. For a simpler thumbnail option, see
108b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     {@link #thumbnail(float)}.
109b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * </p>
110b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
111b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * <p>
112b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     Only the thumbnail call on the main request will be obeyed.
113b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * </p>
114b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
115b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @param thumbnailRequest The request to use to load the thumbnail.
116b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @return This builder object.
117b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     */
118dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> thumbnail(
119dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd            GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType>
12077e0200ba76c89177b6ec8c781f4f8f86984989bSam Judd                    thumbnailRequest) {
121b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        this.thumbnailRequestBuilder = thumbnailRequest;
122b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
123b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        return this;
124b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
125b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
126b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
127b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * Loads an image in an identical manner to this request except with the dimensions of the target multiplied
128b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * by the given size multiplier. If the thumbnail load completes before the fullsize load, the thumbnail will
129b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * be shown. If the thumbnail load completes afer the fullsize load, the thumbnail will not be shown.
130b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
131b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * <p>
132b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     Note - The thumbnail image will be smaller than the size requested so the target (or {@link ImageView})
133b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     must be able to scale the thumbnail appropriately. See {@link ImageView.ScaleType}.
134b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * </p>
135b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
136b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * <p>
137b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     Almost all options will be copied from the original load, including the {@link ModelLoader},
138b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     {@link BitmapDecoder}, and {@link Transformation}s. However, {@link #placeholder(int)} and
139b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     {@link #error(int)}, and {@link #listener(RequestListener)} will only be used on the fullsize load and
140b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     will not be copied for the thumbnail load.
141b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * </p>
142b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
143b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * <p>
144b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     Only the thumbnail call on the main request will be obeyed.
145b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * </p>
146b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
147b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @param sizeMultiplier The multiplier to apply to the {@link Target}'s dimensions when loading the thumbnail.
148b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @return This builder object.
149b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     */
150dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> thumbnail(
15177e0200ba76c89177b6ec8c781f4f8f86984989bSam Judd            float sizeMultiplier) {
152b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        if (sizeMultiplier < 0f || sizeMultiplier > 1f) {
153b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd            throw new IllegalArgumentException("sizeMultiplier must be between 0 and 1");
154b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        }
155b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        this.thumbSizeMultiplier = sizeMultiplier;
156b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
157b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        return this;
158b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
159b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
160b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
161b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * Applies a multiplier to the {@link Target}'s size before loading the image. Useful for loading thumbnails
162b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * or trying to avoid loading huge bitmaps on devices with overly dense screens.
163b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
164b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @param sizeMultiplier The multiplier to apply to the {@link Target}'s dimensions when loading the image.
165b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @return This builder object.
166b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     */
167dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> sizeMultiplier(
168b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd            float sizeMultiplier) {
169b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        if (sizeMultiplier < 0f || sizeMultiplier > 1f) {
170b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd            throw new IllegalArgumentException("sizeMultiplier must be between 0 and 1");
171b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        }
172b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        this.sizeMultiplier = sizeMultiplier;
173b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
174b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        return this;
175b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
176b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
177b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
178dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd     * Loads the resource from the given data type using the given {@link BitmapDecoder}.
179b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
180b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * <p>
181b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *     Will be ignored if the data represented by the given model is not a video.
182b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * </p>
183b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
184b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @param decoder The {@link BitmapDecoder} to use to decode the video resource.
18576fbad3dbce72240e9f5b82c826e3229c1176fb6Sam Judd     * @return This request builder.
186b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     */
187dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> decoder(
188dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd            ResourceDecoder<DataType, ResourceType> decoder) {
1897260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        // loadProvider will be null if model is null, in which case we're not going to load anything so it's ok to
1907260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        // ignore the decoder.
1917260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        if (loadProvider != null) {
1927260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd            loadProvider.setSourceDecoder(decoder);
1937260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        }
194b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
195b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        return this;
196b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
197b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
198dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> cacheDecoder(
1997260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd            ResourceDecoder <InputStream, ResourceType> cacheDecoder) {
2007260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        // loadProvider will be null if model is null, in which case we're not going to load anything so it's ok to
2017260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        // ignore the decoder.
2027260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        if (loadProvider != null) {
2037260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd            loadProvider.setCacheDecoder(cacheDecoder);
2047260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        }
205d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd
206d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd        return this;
207d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd    }
208d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd
209cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd    /**
210cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * Sets the source encoder to use to encode the data retrieved by this request directly into cache. The returned
211cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * resouce will then be decoded from the cached data.
212cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     *
213cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * <p>
214cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     *     Note - This encoder will not be used unless
215cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * </p>
216cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     *
217cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * @param sourceEncoder The encoder to use.
218cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * @return This request builder.
219cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     */
220cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> sourceEncoder(
221cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd            Encoder<DataType> sourceEncoder) {
222cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd        if (loadProvider != null) {
223cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd            loadProvider.setSourceEncoder(sourceEncoder);
224cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd            preSkipSourceEncoder = sourceEncoder;
225cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd        }
226cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd
227cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd        return this;
228cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd    }
229cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd
230cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd    /**
231cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * Attempts to write the data retrieved by this request to cache first and then decodes the resource from the cached
232cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * source data. Only makes sense for remote or transient data as a means of either avoiding downloading the same
233cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * data repeatedly or preserving some content you expect to be removed.
234cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     *
235cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * <p>
236cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     *     Note that if this is set to true the {@link ResourceDecoder} set as the decoder will not be used, instead the
237cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     *     cache decoder will be used.
238cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * </p>
239cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     *
240cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * <p>
241cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     *     If no {@link Encoder} is set or available for the given data type, this may cause the load to fail.
242cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * </p>
243cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     *
244cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * @see #sourceEncoder(Encoder)
245cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * @see #decoder(ResourceDecoder)
246cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * @see #cacheDecoder(ResourceDecoder)
247cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * @see #skipCache(boolean)
248cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     *
249cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * @param cacheSource True to write the data directly to cache .
250cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     * @return This request builder.
251cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd     */
252cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> cacheSource(boolean cacheSource) {
253cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd        this.cacheSource = cacheSource;
254cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd        if (!cacheSource) {
255cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd            if (loadProvider != null) {
256cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd                preSkipSourceEncoder = loadProvider.getSourceEncoder();
257cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd            }
258cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd            final Encoder<DataType> skipCache = NullEncoder.get();
259cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd            return sourceEncoder(skipCache);
260cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd        } else {
261cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd            return sourceEncoder(preSkipSourceEncoder);
262cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd        }
263cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd    }
264cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd
265dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> encoder(
266d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd            ResourceEncoder<ResourceType> encoder) {
2677260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        // loadProvider will be null if model is null, in which case we're not going to load anything so it's ok to
2687260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        // ignore the encoder.
2697260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        if (loadProvider != null) {
2707260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd            loadProvider.setEncoder(encoder);
2717260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd            preSkipEncoder = encoder;
2727260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd        }
273d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd
274d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd        return this;
275d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd    }
276d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd
277b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
27808b61677e60069ba681b56cf6312fc0b92020962Sam Judd     * Sets the priority for this load.
27908b61677e60069ba681b56cf6312fc0b92020962Sam Judd     *
28008b61677e60069ba681b56cf6312fc0b92020962Sam Judd     * @param priority A priority.
28108b61677e60069ba681b56cf6312fc0b92020962Sam Judd     * @return This request builder.
28208b61677e60069ba681b56cf6312fc0b92020962Sam Judd     */
283dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> priority(
284d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd            Priority priority) {
28508b61677e60069ba681b56cf6312fc0b92020962Sam Judd        this.priority = priority;
28608b61677e60069ba681b56cf6312fc0b92020962Sam Judd
28708b61677e60069ba681b56cf6312fc0b92020962Sam Judd        return this;
28808b61677e60069ba681b56cf6312fc0b92020962Sam Judd    }
28908b61677e60069ba681b56cf6312fc0b92020962Sam Judd
290b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
291b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * Transform images with the given {@link Transformation}. Appends this transformation onto any existing
292b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * transformations
293b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
294b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @param transformation the transformation to apply.
295b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @return This RequestBuilder
296b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     */
297dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> transform(
29844e0516ee31912216c9e668c255f2d5baf86ac6dSam Judd            Transformation<ResourceType> transformation) {
299ee914288218f2fa29a96ed746c9bd9995857c8cdSam Judd        if (singleTransformation == UnitTransformation.get()) {
3001f028c8ef85fdd1608c7d716d41e7e086fc77359Sam Judd            singleTransformation = transformation;
3011f028c8ef85fdd1608c7d716d41e7e086fc77359Sam Judd        } else {
3021f028c8ef85fdd1608c7d716d41e7e086fc77359Sam Judd            transformations = new ArrayList<Transformation<ResourceType>>();
3031f028c8ef85fdd1608c7d716d41e7e086fc77359Sam Judd            transformations.add(singleTransformation);
3041f028c8ef85fdd1608c7d716d41e7e086fc77359Sam Judd            transformations.add(transformation);
3051f028c8ef85fdd1608c7d716d41e7e086fc77359Sam Judd        }
306b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
307b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        return this;
308b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
309b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
310dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> transcoder(
311d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd            ResourceTranscoder<ResourceType, TranscodeType> transcoder) {
312dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd        if (loadProvider != null) {
313dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd            loadProvider.setTranscoder(transcoder);
314d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd        }
315d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd
316d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd        return this;
317d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd    }
318d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd
319b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
320b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * Sets an animation to run on the wrapped target when an image load finishes. Will only be run if the image
321b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * was loaded asynchronously (ie was not in the memory cache)
322b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
323b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @param animationId The resource id of the animation to run
324b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @return This RequestBuilder
325b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     */
326531667420f0cb59e01e0ae5928392469006148ddSam Judd    // This is safe because the view animation doesn't care about the resource type it receives.
327531667420f0cb59e01e0ae5928392469006148ddSam Judd    @SuppressWarnings("unchecked")
328dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> animate(
329d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd            int animationId) {
330531667420f0cb59e01e0ae5928392469006148ddSam Judd        return animate(new ViewAnimation.ViewAnimationFactory(context, animationId));
331b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
332b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
333b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
334a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     * Sets an animation to run on the wrapped target when an image load finishes. Will only be run if the image
335a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     * was loaded asynchronously (ie was not in the memory cache)
336a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     *
337a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     * @param animation The animation to run
338a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     * @return This RequestBuilder
339a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     */
340531667420f0cb59e01e0ae5928392469006148ddSam Judd    // This is safe because the view animation doesn't care about the resource type it receives.
341531667420f0cb59e01e0ae5928392469006148ddSam Judd    @SuppressWarnings("unchecked")
342dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> animate(
343d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd            Animation animation) {
344531667420f0cb59e01e0ae5928392469006148ddSam Judd        return animate(new ViewAnimation.ViewAnimationFactory(animation));
345531667420f0cb59e01e0ae5928392469006148ddSam Judd    }
346531667420f0cb59e01e0ae5928392469006148ddSam Judd
347531667420f0cb59e01e0ae5928392469006148ddSam Judd    /**
348531667420f0cb59e01e0ae5928392469006148ddSam Judd     * Sets an animator to run a {@link ViewPropertyAnimator} on a view that the target may be wrapping when a resource
349531667420f0cb59e01e0ae5928392469006148ddSam Judd     * load finishes. Will only be run if the load was loaded asynchronously (ie was not in the memory cache).
350531667420f0cb59e01e0ae5928392469006148ddSam Judd     *
351531667420f0cb59e01e0ae5928392469006148ddSam Judd     * @param animator The {@link ViewPropertyAnimation.Animator} to run.
352531667420f0cb59e01e0ae5928392469006148ddSam Judd     * @return This RequestBuilder.
353531667420f0cb59e01e0ae5928392469006148ddSam Judd     */
354531667420f0cb59e01e0ae5928392469006148ddSam Judd    // This is safe because the view property animation doesn't care about the resource type it receives.
355531667420f0cb59e01e0ae5928392469006148ddSam Judd    @SuppressWarnings("unchecked")
356531667420f0cb59e01e0ae5928392469006148ddSam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> animate(
357531667420f0cb59e01e0ae5928392469006148ddSam Judd            ViewPropertyAnimation.Animator animator) {
358531667420f0cb59e01e0ae5928392469006148ddSam Judd        return animate(new ViewPropertyAnimation.ViewPropertyAnimationFactory(animator));
359531667420f0cb59e01e0ae5928392469006148ddSam Judd    }
360531667420f0cb59e01e0ae5928392469006148ddSam Judd
361531667420f0cb59e01e0ae5928392469006148ddSam Judd    GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> animate(
362531667420f0cb59e01e0ae5928392469006148ddSam Judd            GlideAnimationFactory<TranscodeType> animationFactory) {
363531667420f0cb59e01e0ae5928392469006148ddSam Judd        if (animationFactory == null) {
364531667420f0cb59e01e0ae5928392469006148ddSam Judd            throw new NullPointerException("Animation factory must not be null!");
365531667420f0cb59e01e0ae5928392469006148ddSam Judd        }
366531667420f0cb59e01e0ae5928392469006148ddSam Judd        this.animationFactory = animationFactory;
367a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd
368a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd        return this;
369a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd    }
370a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd
371a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd    /**
372b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * Sets a resource to display while an image is loading
373b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
374b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @param resourceId The id of the resource to use as a placeholder
375b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @return This RequestBuilder
376b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     */
377dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> placeholder(
378d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd            int resourceId) {
379b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        this.placeholderId = resourceId;
380b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
381b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        return this;
382b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
383b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
384b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
385a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     * Sets a drawable to display while an image is loading.
386a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     *
387a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     * @param drawable The drawable to display as a placeholder.
388a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     * @return This RequestBuilder.
389a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     */
390dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> placeholder(
391d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd            Drawable drawable) {
392a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd        this.placeholderDrawable = drawable;
393a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd
394a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd        return this;
395a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd    }
396a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd
397a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd    /**
398b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * Sets a resource to display if a load fails
399b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
400b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @param resourceId The id of the resource to use as a placeholder
401b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @return This request
402b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     */
403dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> error(
404d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd            int resourceId) {
405b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        this.errorId = resourceId;
406b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
407b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        return this;
408b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
409b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
410b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
411a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     * Sets a {@link Drawable} to display if a load fails.
412a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     *
413a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     * @param drawable The drawable to display.
414a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     * @return This RequestBuilder.
415a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd     */
416dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> error(
417d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd            Drawable drawable) {
418a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd        this.errorPlaceholder = drawable;
419a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd
420a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd        return this;
421a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd    }
422a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd
423a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd    /**
424b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * Sets a RequestBuilder listener to monitor the image load. It's best to create a single instance of an
425b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * exception handler per type of request (usually activity/fragment) rather than pass one in per request to
426b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * avoid some redundant object allocation.
427b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
42880b7691daac313059e4311214249fa6da53451edSam Judd     * @param requestListener The request listener to use.
42980b7691daac313059e4311214249fa6da53451edSam Judd     * @return This RequestBuilder.
430b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     */
431dbb67f826b0e76645c809be6d589e9dcb8271324Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> listener(
432444371118bf079a412017948166cf4eb4db48103Sam Judd            RequestListener<ModelType, TranscodeType> requestListener) {
433b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        this.requestListener = requestListener;
434b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
435b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        return this;
436b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
437b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
438b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    /**
43980b7691daac313059e4311214249fa6da53451edSam Judd     * Allows the loaded resource to skip the memory cache.
44080b7691daac313059e4311214249fa6da53451edSam Judd     *
44180b7691daac313059e4311214249fa6da53451edSam Judd     * <p>
44280b7691daac313059e4311214249fa6da53451edSam Judd     *     Note - this is not a guarantee. If a request is already pending for this resource and that request is not
44380b7691daac313059e4311214249fa6da53451edSam Judd     *     also skipping the memory cache, the resource will be cached in memory.
44480b7691daac313059e4311214249fa6da53451edSam Judd     * </p>
44580b7691daac313059e4311214249fa6da53451edSam Judd     *
44680b7691daac313059e4311214249fa6da53451edSam Judd     * @param skip True to allow the resource to skip the memory cache.
44780b7691daac313059e4311214249fa6da53451edSam Judd     * @return This RequestBuilder.
44880b7691daac313059e4311214249fa6da53451edSam Judd     */
44980b7691daac313059e4311214249fa6da53451edSam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> skipMemoryCache(boolean skip) {
45080b7691daac313059e4311214249fa6da53451edSam Judd        this.isCacheable = !skip;
45180b7691daac313059e4311214249fa6da53451edSam Judd
45280b7691daac313059e4311214249fa6da53451edSam Judd        return this;
45380b7691daac313059e4311214249fa6da53451edSam Judd    }
45480b7691daac313059e4311214249fa6da53451edSam Judd
45580b7691daac313059e4311214249fa6da53451edSam Judd    /**
45680b7691daac313059e4311214249fa6da53451edSam Judd     * Allows the loaded resource to skip the disk cache.
45780b7691daac313059e4311214249fa6da53451edSam Judd     *
45880b7691daac313059e4311214249fa6da53451edSam Judd     * <p>
45980b7691daac313059e4311214249fa6da53451edSam Judd     *     Note - this is not a guarantee. If a request is already pending for this resource and that request is not
46080b7691daac313059e4311214249fa6da53451edSam Judd     *     also skipping the disk cache, the resource will be cached on disk.
46180b7691daac313059e4311214249fa6da53451edSam Judd     * </p>
46280b7691daac313059e4311214249fa6da53451edSam Judd     *
46380b7691daac313059e4311214249fa6da53451edSam Judd     * @param skip True to allow the resource to skip the disk cache.
46480b7691daac313059e4311214249fa6da53451edSam Judd     * @return This RequestBuilder.
46580b7691daac313059e4311214249fa6da53451edSam Judd     */
46680b7691daac313059e4311214249fa6da53451edSam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> skipDiskCache(boolean skip) {
46780b7691daac313059e4311214249fa6da53451edSam Judd        if (skip) {
4687260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd            if (loadProvider != null) {
4697260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd                preSkipEncoder = loadProvider.getEncoder();
4707260e7b8e840ae9e03cc20df73accfc4121cb190Sam Judd            }
47180b7691daac313059e4311214249fa6da53451edSam Judd            final SkipCache<ResourceType> skipCache = SkipCache.get();
47280b7691daac313059e4311214249fa6da53451edSam Judd            return encoder(skipCache);
47380b7691daac313059e4311214249fa6da53451edSam Judd        } else {
47480b7691daac313059e4311214249fa6da53451edSam Judd            return encoder(preSkipEncoder);
47580b7691daac313059e4311214249fa6da53451edSam Judd        }
47680b7691daac313059e4311214249fa6da53451edSam Judd    }
47780b7691daac313059e4311214249fa6da53451edSam Judd
47880b7691daac313059e4311214249fa6da53451edSam Judd    /**
47980b7691daac313059e4311214249fa6da53451edSam Judd     * Allows the resource to skip both the memory and the disk cache.
48080b7691daac313059e4311214249fa6da53451edSam Judd     *
48180b7691daac313059e4311214249fa6da53451edSam Judd     * @see #skipDiskCache(boolean)
48280b7691daac313059e4311214249fa6da53451edSam Judd     * @see #skipMemoryCache(boolean)
48380b7691daac313059e4311214249fa6da53451edSam Judd     *
48480b7691daac313059e4311214249fa6da53451edSam Judd     * @param skip True to allow the resource to skip both the memory and the disk cache.
48580b7691daac313059e4311214249fa6da53451edSam Judd     * @return This RequestBuilder.
48680b7691daac313059e4311214249fa6da53451edSam Judd     */
48780b7691daac313059e4311214249fa6da53451edSam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> skipCache(boolean skip) {
48880b7691daac313059e4311214249fa6da53451edSam Judd        skipMemoryCache(skip);
48980b7691daac313059e4311214249fa6da53451edSam Judd        skipDiskCache(skip);
490cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd        cacheSource(false);
49180b7691daac313059e4311214249fa6da53451edSam Judd
49280b7691daac313059e4311214249fa6da53451edSam Judd        return this;
49380b7691daac313059e4311214249fa6da53451edSam Judd    }
49480b7691daac313059e4311214249fa6da53451edSam Judd
49580b7691daac313059e4311214249fa6da53451edSam Judd    /**
496b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd     * Overrides the {@link Target}'s width and height with the given values. This is useful almost exclusively for
497b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd     * thumbnails, and should only be used when you both need a very specific sized image and when it is impossible or
498b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd     * impractical to return that size from {@link Target#getSize(Target.SizeReadyCallback)}.
499b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd     *
500b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd     * @param width The width to use to load the resource.
501b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd     * @param height The height to use to load the resource.
502b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd     * @return This RequestBuilder.
503b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd     */
504b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> override(int width, int height) {
505b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd        if (width <= 0) {
506b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd            throw new IllegalArgumentException("Width must be >= 0");
507b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd        }
508b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd        if (height <= 0) {
509b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd            throw new IllegalArgumentException("Height must be >= 0");
510b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd        }
511b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd        this.overrideWidth = width;
512b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd        this.overrideHeight = height;
513b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd
514b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd        return this;
515b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd    }
516b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd
517b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd    /**
518b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * Set the target the image will be loaded into.
519b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     *
520b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @param target The target to load te image for
521b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     * @return The given target.
522b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd     */
52377e0200ba76c89177b6ec8c781f4f8f86984989bSam Judd    public <Y extends Target<TranscodeType>> Y into(Y target) {
524785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd        Request previous = target.getRequest();
5258a6067fbe2a670d2e893c79c9c0ec17817da6568Sam Judd
526b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        if (previous != null) {
527b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd            previous.clear();
528667fb8129df68fbab0c489b23b2ca9d392cd45a0Sam Judd            requestTracker.removeRequest(previous);
529d0546ba0366fc276a5ac1f4c2eea88901166f7beSam Judd            previous.recycle();
530b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        }
531b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
532785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd        Request request = buildRequest(target);
533b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        target.setRequest(request);
534667fb8129df68fbab0c489b23b2ca9d392cd45a0Sam Judd        requestTracker.addRequest(request);
535667fb8129df68fbab0c489b23b2ca9d392cd45a0Sam Judd        request.run();
536667fb8129df68fbab0c489b23b2ca9d392cd45a0Sam Judd
537b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        return target;
538b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
539b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
540785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd    /**
541785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd     * Sets the {@link ImageView} the image will be loaded into, cancels any existing loads into the view, and frees
542785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd     * any resources Glide has loaded into the view so they may be reused.
543785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd     *
544785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd     * @see Glide#clear(View)
545785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd     *
546785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd     * @param view The view to cancel previous loads for and load the new image into.
547785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd     * @return The {@link BitmapImageViewTarget} used to wrap the given {@link ImageView}.
548785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd     */
54977e0200ba76c89177b6ec8c781f4f8f86984989bSam Judd    public Target<TranscodeType> into(ImageView view) {
550d3bd0a915d197e08dc7d2c7cf97fb0ee77049f51Sam Judd        return into(glide.buildImageViewTarget(view, transcodeClass));
551785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd    }
552785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd
55356058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger    private Priority getThumbnailPriority() {
55456058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger        final Priority result;
55556058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger        if (priority == Priority.LOW) {
55656058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            result = Priority.NORMAL;
55756058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger        } else if (priority == Priority.NORMAL) {
55856058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            result = Priority.HIGH;
55956058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger        } else {
56056058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            result = Priority.IMMEDIATE;
56156058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger        }
56256058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger        return result;
56356058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger    }
564f9ccb9c6c3f50832993459b83746567dfeb6acbaSam Judd
56556058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger    private Request buildRequest(Target<TranscodeType> target) {
56608b61677e60069ba681b56cf6312fc0b92020962Sam Judd        if (priority == null) {
5679bebdf4ee5dcaa1569bea3985dfe08f93ed8bd38Sam Judd            priority = Priority.NORMAL;
56808b61677e60069ba681b56cf6312fc0b92020962Sam Judd        }
56956058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger        return buildRequestRecursive(target, null);
57056058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger    }
571e9498d0b46d4c79410968eb11c332c42c9be7ec0Sam Judd
57256058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger    private Request buildRequestRecursive(Target<TranscodeType> target, ThumbnailRequestCoordinator parentCoordinator) {
573b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        if (thumbnailRequestBuilder != null) {
57456058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            // Recursive case: contains a potentially recursive thumbnail request builder.
575531667420f0cb59e01e0ae5928392469006148ddSam Judd            if (thumbnailRequestBuilder.animationFactory.equals(NoAnimation.getFactory())) {
576531667420f0cb59e01e0ae5928392469006148ddSam Judd                thumbnailRequestBuilder.animationFactory = animationFactory;
577a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd            }
578a76c1d39daf35a8375fea219cdd69c1dd56a276fSam Judd
579b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd            if (thumbnailRequestBuilder.requestListener == null && requestListener != null) {
580b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd                thumbnailRequestBuilder.requestListener = requestListener;
581b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd            }
58208b61677e60069ba681b56cf6312fc0b92020962Sam Judd
58308b61677e60069ba681b56cf6312fc0b92020962Sam Judd            if (thumbnailRequestBuilder.priority == null) {
58408b61677e60069ba681b56cf6312fc0b92020962Sam Judd                thumbnailRequestBuilder.priority = getThumbnailPriority();
58508b61677e60069ba681b56cf6312fc0b92020962Sam Judd            }
58608b61677e60069ba681b56cf6312fc0b92020962Sam Judd
58756058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
58856058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
58956058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            // Recursively generate thumbnail requests.
59056058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            Request thumbRequest = thumbnailRequestBuilder.buildRequestRecursive(target, coordinator);
59156058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            coordinator.setRequests(fullRequest, thumbRequest);
59256058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            return coordinator;
593b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        } else if (thumbSizeMultiplier != null) {
59456058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            // Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
59556058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
59656058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
59756058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            Request thumbnailRequest = obtainRequest(target, thumbSizeMultiplier, getThumbnailPriority(), coordinator);
59856058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            coordinator.setRequests(fullRequest, thumbnailRequest);
59956058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            return coordinator;
600b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        } else {
60156058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            // Base case: no thumbnail.
60256058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            return obtainRequest(target, sizeMultiplier, priority, parentCoordinator);
603b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        }
604b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
605b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd
60656058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger    private <Z> Request obtainRequest(Target<TranscodeType> target, float sizeMultiplier, Priority priority,
60727eb05702fd4531d6974640c62df1d569629edb6Sam Judd            RequestCoordinator requestCoordinator) {
608f9ccb9c6c3f50832993459b83746567dfeb6acbaSam Judd        if (model == null) {
60956058fb1edadec8c92e604e74bde41cdf612a78eAlan Newberger            requestCoordinator = null;
61027eb05702fd4531d6974640c62df1d569629edb6Sam Judd        }
61127eb05702fd4531d6974640c62df1d569629edb6Sam Judd
612d0546ba0366fc276a5ac1f4c2eea88901166f7beSam Judd        return GenericRequest.obtain(
613531667420f0cb59e01e0ae5928392469006148ddSam Judd                loadProvider,
614531667420f0cb59e01e0ae5928392469006148ddSam Judd                model,
615531667420f0cb59e01e0ae5928392469006148ddSam Judd                context,
616531667420f0cb59e01e0ae5928392469006148ddSam Judd                priority,
617531667420f0cb59e01e0ae5928392469006148ddSam Judd                target,
618531667420f0cb59e01e0ae5928392469006148ddSam Judd                sizeMultiplier,
619531667420f0cb59e01e0ae5928392469006148ddSam Judd                placeholderDrawable,
620531667420f0cb59e01e0ae5928392469006148ddSam Judd                placeholderId,
621531667420f0cb59e01e0ae5928392469006148ddSam Judd                errorPlaceholder,
622531667420f0cb59e01e0ae5928392469006148ddSam Judd                errorId,
623531667420f0cb59e01e0ae5928392469006148ddSam Judd                requestListener,
624531667420f0cb59e01e0ae5928392469006148ddSam Judd                requestCoordinator,
625531667420f0cb59e01e0ae5928392469006148ddSam Judd                glide.getEngine(),
626531667420f0cb59e01e0ae5928392469006148ddSam Judd                getFinalTransformation(),
627531667420f0cb59e01e0ae5928392469006148ddSam Judd                transcodeClass,
628531667420f0cb59e01e0ae5928392469006148ddSam Judd                isCacheable,
629b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd                animationFactory,
630b46fae747f6bf04b849442f851a1c9da51434ec1Sam Judd                overrideWidth,
631cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd                overrideHeight,
632cf1e05bf226ce4e7a510a5f7cac0661b9b2e90e9Sam Judd                cacheSource);
633e9498d0b46d4c79410968eb11c332c42c9be7ec0Sam Judd    }
634e9498d0b46d4c79410968eb11c332c42c9be7ec0Sam Judd
63531b60a4ba485dcc22e5edd19c6768e1141c32f4eSam Judd    @SuppressWarnings("unchecked")
63644e0516ee31912216c9e668c255f2d5baf86ac6dSam Judd    private Transformation<ResourceType> getFinalTransformation() {
6371f028c8ef85fdd1608c7d716d41e7e086fc77359Sam Judd        if (transformations == null) {
6381f028c8ef85fdd1608c7d716d41e7e086fc77359Sam Judd            return singleTransformation;
6391f028c8ef85fdd1608c7d716d41e7e086fc77359Sam Judd        } else {
6401f028c8ef85fdd1608c7d716d41e7e086fc77359Sam Judd            return new MultiTransformation<ResourceType>(transformations);
641b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd        }
642b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd    }
643b8963a023ceb009cbf7f73a4506e7af7e693a219Sam Judd}
644