BitmapDrawableImageView.java revision d7654f820a99358a7d2b2afb9b3a174690e213f6
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.bitmap.view;
18
19import android.content.Context;
20import android.graphics.Bitmap;
21import android.graphics.drawable.Drawable;
22import android.net.Uri;
23import android.os.Build;
24import android.util.AttributeSet;
25import android.widget.ImageView;
26
27import com.android.bitmap.drawable.BasicBitmapDrawable;
28
29/**
30 * A helpful ImageView replacement that can generally be used in lieu of ImageView.
31 * BitmapDrawableImageView has logic to unbind its BasicBitmapDrawable when it is detached from the
32 * window.
33 */
34public class BitmapDrawableImageView extends ImageView {
35    private static final boolean hasTransientStateSupported =
36        Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
37    private BasicBitmapDrawable mDrawable;
38    private boolean mAttachedToWindow;
39
40    public BitmapDrawableImageView(final Context context) {
41        this(context, null);
42    }
43
44    public BitmapDrawableImageView(final Context context, final AttributeSet attrs) {
45        this(context, attrs, 0);
46    }
47
48    public BitmapDrawableImageView(final Context context, final AttributeSet attrs,
49            final int defStyle) {
50        super(context, attrs, defStyle);
51    }
52
53    /**
54     * Get the source drawable for this BitmapDrawableImageView.
55     * @return The source drawable casted to the given type, or null if the type does not match.
56     */
57    @SuppressWarnings("unchecked") // Cast to type parameter.
58    public <E extends BasicBitmapDrawable> E getTypedDrawable() {
59        try {
60            return (E) mDrawable;
61        } catch (Exception ignored) {
62            return null;
63        }
64    }
65
66    /**
67     * Set the given drawable as the source for this BitmapDrawableImageView.
68     * @param drawable The source drawable.
69     */
70    public <E extends BasicBitmapDrawable> void setTypedDrawable(E drawable) {
71        super.setImageDrawable(drawable);
72        unbindDrawable();
73        mDrawable = drawable;
74    }
75
76    private void unbindDrawable() {
77        if (mDrawable != null) {
78            mDrawable.unbind();
79        }
80    }
81
82    @Override
83    public void setImageResource(final int resId) {
84        super.setImageResource(resId);
85        unbindDrawable();
86        mDrawable = null;
87    }
88
89    @Override
90    public void setImageURI(final Uri uri) {
91        super.setImageURI(uri);
92        unbindDrawable();
93        mDrawable = null;
94    }
95
96    @Override
97    public void setImageDrawable(final Drawable drawable) {
98        super.setImageDrawable(drawable);
99        unbindDrawable();
100        mDrawable = null;
101    }
102
103    @Override
104    public void setImageBitmap(final Bitmap bm) {
105        super.setImageBitmap(bm);
106        unbindDrawable();
107        mDrawable = null;
108    }
109
110    @Override
111    protected void onAttachedToWindow() {
112        super.onAttachedToWindow();
113        mAttachedToWindow = true;
114    }
115
116    @Override
117    protected void onDetachedFromWindow() {
118        super.onDetachedFromWindow();
119        mAttachedToWindow = false;
120        if (hasTransientStateSupported && !hasTransientState()) {
121            unbindDrawable();
122        }
123    }
124
125    @Override
126    public void setHasTransientState(boolean hasTransientState) {
127        super.setHasTransientState(hasTransientState);
128        if (!hasTransientState && !mAttachedToWindow) {
129            unbindDrawable();
130        }
131    }
132}
133