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 
17 package com.example.android.displayingbitmaps.ui;
18 
19 import android.content.Context;
20 import android.graphics.drawable.Drawable;
21 import android.graphics.drawable.LayerDrawable;
22 import android.util.AttributeSet;
23 import android.widget.ImageView;
24 
25 import com.example.android.displayingbitmaps.util.RecyclingBitmapDrawable;
26 
27 /**
28  * Sub-class of ImageView which automatically notifies the drawable when it is
29  * being displayed.
30  */
31 public class RecyclingImageView extends ImageView {
32 
RecyclingImageView(Context context)33     public RecyclingImageView(Context context) {
34         super(context);
35     }
36 
RecyclingImageView(Context context, AttributeSet attrs)37     public RecyclingImageView(Context context, AttributeSet attrs) {
38         super(context, attrs);
39     }
40 
41     /**
42      * @see android.widget.ImageView#onDetachedFromWindow()
43      */
44     @Override
onDetachedFromWindow()45     protected void onDetachedFromWindow() {
46         // This has been detached from Window, so clear the drawable
47         setImageDrawable(null);
48 
49         super.onDetachedFromWindow();
50     }
51 
52     /**
53      * @see android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)
54      */
55     @Override
setImageDrawable(Drawable drawable)56     public void setImageDrawable(Drawable drawable) {
57         // Keep hold of previous Drawable
58         final Drawable previousDrawable = getDrawable();
59 
60         // Call super to set new Drawable
61         super.setImageDrawable(drawable);
62 
63         // Notify new Drawable that it is being displayed
64         notifyDrawable(drawable, true);
65 
66         // Notify old Drawable so it is no longer being displayed
67         notifyDrawable(previousDrawable, false);
68     }
69 
70     /**
71      * Notifies the drawable that it's displayed state has changed.
72      *
73      * @param drawable
74      * @param isDisplayed
75      */
notifyDrawable(Drawable drawable, final boolean isDisplayed)76     private static void notifyDrawable(Drawable drawable, final boolean isDisplayed) {
77         if (drawable instanceof RecyclingBitmapDrawable) {
78             // The drawable is a CountingBitmapDrawable, so notify it
79             ((RecyclingBitmapDrawable) drawable).setIsDisplayed(isDisplayed);
80         } else if (drawable instanceof LayerDrawable) {
81             // The drawable is a LayerDrawable, so recurse on each layer
82             LayerDrawable layerDrawable = (LayerDrawable) drawable;
83             for (int i = 0, z = layerDrawable.getNumberOfLayers(); i < z; i++) {
84                 notifyDrawable(layerDrawable.getDrawable(i), isDisplayed);
85             }
86         }
87     }
88 
89 }
90