1package com.bumptech.glide.request.target;
2
3import android.widget.ImageView;
4
5import com.bumptech.glide.load.resource.drawable.GlideDrawable;
6import com.bumptech.glide.request.animation.GlideAnimation;
7
8/**
9 * A {@link com.bumptech.glide.request.target.Target} that can display an {@link android.graphics.drawable.Drawable} in
10 * an {@link android.widget.ImageView}.
11 */
12public class GlideDrawableImageViewTarget extends ImageViewTarget<GlideDrawable> {
13    private static final float SQUARE_RATIO_MARGIN = 0.05f;
14    private int maxLoopCount;
15    private GlideDrawable resource;
16
17    /**
18     * Constructor for an {@link com.bumptech.glide.request.target.Target} that can display an
19     * {@link com.bumptech.glide.load.resource.drawable.GlideDrawable} in an {@link android.widget.ImageView}.
20     *
21     * @param view The view to display the drawable in.
22     */
23    public GlideDrawableImageViewTarget(ImageView view) {
24        this(view, GlideDrawable.LOOP_FOREVER);
25    }
26
27    /**
28     * Constructor for an {@link com.bumptech.glide.request.target.Target} that can display an
29     * {@link com.bumptech.glide.load.resource.drawable.GlideDrawable} in an {@link android.widget.ImageView}.
30     *
31     * @param view The view to display the drawable in.
32     * @param maxLoopCount A value to pass to to {@link com.bumptech.glide.load.resource.drawable.GlideDrawable}s
33     *                     indicating how many times they should repeat their animation (if they have one). See
34     *                     {@link com.bumptech.glide.load.resource.drawable.GlideDrawable#setLoopCount(int)}.
35     */
36    public GlideDrawableImageViewTarget(ImageView view, int maxLoopCount) {
37        super(view);
38        this.maxLoopCount = maxLoopCount;
39    }
40
41    /**
42     * {@inheritDoc}
43     * If no {@link com.bumptech.glide.request.animation.GlideAnimation} is given or if the animation does not set the
44     * {@link android.graphics.drawable.Drawable} on the view, the drawable is set using
45     * {@link android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
46     *
47     * @param resource {@inheritDoc}
48     * @param animation {@inheritDoc}
49     */
50    @Override
51    public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {
52        if (!resource.isAnimated()) {
53            //TODO: Try to generalize this to other sizes/shapes.
54            // This is a dirty hack that tries to make loading square thumbnails and then square full images less costly
55            // by forcing both the smaller thumb and the larger version to have exactly the same intrinsic dimensions.
56            // If a drawable is replaced in an ImageView by another drawable with different intrinsic dimensions,
57            // the ImageView requests a layout. Scrolling rapidly while replacing thumbs with larger images triggers
58            // lots of these calls and causes significant amounts of jank.
59            float viewRatio = view.getWidth() / (float) view.getHeight();
60            float drawableRatio = resource.getIntrinsicWidth() / (float) resource.getIntrinsicHeight();
61            if (Math.abs(viewRatio - 1f) <= SQUARE_RATIO_MARGIN
62                    && Math.abs(drawableRatio - 1f) <= SQUARE_RATIO_MARGIN) {
63                resource = new SquaringDrawable(resource, view.getWidth());
64            }
65        }
66        super.onResourceReady(resource, animation);
67        this.resource = resource;
68        resource.setLoopCount(maxLoopCount);
69        resource.start();
70    }
71
72    /**
73     * Sets the drawable on the view using
74     * {@link android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
75     *
76     * @param resource The {@link android.graphics.drawable.Drawable} to display in the view.
77     */
78    @Override
79    protected void setResource(GlideDrawable resource) {
80        view.setImageDrawable(resource);
81    }
82
83    @Override
84    public void onStart() {
85        if (resource != null) {
86            resource.start();
87        }
88    }
89
90    @Override
91    public void onStop() {
92        if (resource != null) {
93            resource.stop();
94        }
95    }
96}
97