NetworkImageView.java revision baa2ff70bea2dbfb89d6732902e6b2bd6de7d207
1d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod/** 2d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * Copyright (C) 2013 The Android Open Source Project 3d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * 4d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * Licensed under the Apache License, Version 2.0 (the "License"); 5d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * you may not use this file except in compliance with the License. 6d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * You may obtain a copy of the License at 7d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * 8d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * http://www.apache.org/licenses/LICENSE-2.0 9d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * 10d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * Unless required by applicable law or agreed to in writing, software 11d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * distributed under the License is distributed on an "AS IS" BASIS, 12d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * See the License for the specific language governing permissions and 14d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * limitations under the License. 15d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod */ 16d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbodpackage com.android.volley.toolbox; 17d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 18d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbodimport android.content.Context; 19d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbodimport android.text.TextUtils; 20d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbodimport android.util.AttributeSet; 21c3dce982fb05a7674d360255a9831adf83475099Vladimir Baryshnikovimport android.view.ViewGroup.LayoutParams; 22d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbodimport android.widget.ImageView; 23d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 24b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbodimport com.android.volley.VolleyError; 25d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbodimport com.android.volley.toolbox.ImageLoader.ImageContainer; 26b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbodimport com.android.volley.toolbox.ImageLoader.ImageListener; 27d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 28d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod/** 29d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * Handles fetching an image from a URL as well as the life-cycle of the 30d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * associated request. 31d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod */ 32d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbodpublic class NetworkImageView extends ImageView { 33d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod /** The URL of the network image to load */ 34d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod private String mUrl; 35d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 36d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod /** 37d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * Resource ID of the image to be used as a placeholder until the network image is loaded. 38d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod */ 39d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod private int mDefaultImageId; 40d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 41d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod /** 42d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * Resource ID of the image to be used if the network response fails. 43d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod */ 44d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod private int mErrorImageId; 45d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 46d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod /** Local copy of the ImageLoader. */ 47d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod private ImageLoader mImageLoader; 48d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 49da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton /** Current ImageContainer. (either in-flight or finished) */ 50da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton private ImageContainer mImageContainer; 51da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton 52d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod public NetworkImageView(Context context) { 53d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod this(context, null); 54d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 55d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 56d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod public NetworkImageView(Context context, AttributeSet attrs) { 57d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod this(context, attrs, 0); 58d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 59d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 60d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod public NetworkImageView(Context context, AttributeSet attrs, int defStyle) { 61d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod super(context, attrs, defStyle); 62d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 63d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 64d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod /** 65d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * Sets URL of the image that should be loaded into this view. Note that calling this will 66d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * immediately either set the cached image (if available) or the default image specified by 67d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * {@link NetworkImageView#setDefaultImageResId(int)} on the view. 68d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * 69d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * NOTE: If applicable, {@link NetworkImageView#setDefaultImageResId(int)} and 70d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * {@link NetworkImageView#setErrorImageResId(int)} should be called prior to calling 71d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * this function. 72d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * 73d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * @param url The URL that should be loaded into this ImageView. 74d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * @param imageLoader ImageLoader that will be used to make the request. 75d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod */ 76d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod public void setImageUrl(String url, ImageLoader imageLoader) { 77d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod mUrl = url; 78d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod mImageLoader = imageLoader; 79d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod // The URL has potentially changed. See if we need to load it. 80b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod loadImageIfNecessary(false); 81d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 82d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 83d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod /** 84d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * Sets the default image resource ID to be used for this view until the attempt to load it 85d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * completes. 86d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod */ 87d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod public void setDefaultImageResId(int defaultImage) { 88d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod mDefaultImageId = defaultImage; 89d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 90d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 91d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod /** 92d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * Sets the error image resource ID to be used for this view in the event that the image 93d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * requested fails to load. 94d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod */ 95d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod public void setErrorImageResId(int errorImage) { 96d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod mErrorImageId = errorImage; 97d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 98d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 99d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod /** 100d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod * Loads the image for the view if it isn't already loaded. 101b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod * @param isInLayoutPass True if this was invoked from a layout pass, false otherwise. 102d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod */ 103baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod void loadImageIfNecessary(final boolean isInLayoutPass) { 104d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod int width = getWidth(); 105d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod int height = getHeight(); 106d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 107baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod boolean wrapWidth = false, wrapHeight = false; 108baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod if (getLayoutParams() != null) { 109baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod wrapWidth = getLayoutParams().width == LayoutParams.WRAP_CONTENT; 110baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod wrapHeight = getLayoutParams().height == LayoutParams.WRAP_CONTENT; 111baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod } 112baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod 113aa6a5e69c646e8ef926a794a031ca4a9b5526a89Aurash Mahbod // if the view's bounds aren't known yet, and this is not a wrap-content/wrap-content 114aa6a5e69c646e8ef926a794a031ca4a9b5526a89Aurash Mahbod // view, hold off on loading the image. 115baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod boolean isFullyWrapContent = wrapWidth && wrapHeight; 116aa6a5e69c646e8ef926a794a031ca4a9b5526a89Aurash Mahbod if (width == 0 && height == 0 && !isFullyWrapContent) { 117d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod return; 118d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 119d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 120d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod // if the URL to be loaded in this view is empty, cancel any old requests and clear the 121d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod // currently loaded image. 122d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod if (TextUtils.isEmpty(mUrl)) { 123da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton if (mImageContainer != null) { 124da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton mImageContainer.cancelRequest(); 125da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton mImageContainer = null; 126d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 12754086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown setDefaultImageOrNull(); 128d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod return; 129d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 130d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 131d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod // if there was an old request in this view, check if it needs to be canceled. 132da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton if (mImageContainer != null && mImageContainer.getRequestUrl() != null) { 133da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton if (mImageContainer.getRequestUrl().equals(mUrl)) { 134d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod // if the request is from the same URL, return. 135d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod return; 136d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } else { 137d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod // if there is a pre-existing request, cancel it if it's fetching a different URL. 138da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton mImageContainer.cancelRequest(); 13954086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown setDefaultImageOrNull(); 140d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 141d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 142d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 143baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod // Calculate the max image width / height to use while ignoring WRAP_CONTENT dimens. 144baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod int maxWidth = wrapWidth ? 0 : width; 145baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod int maxHeight = wrapHeight ? 0 : height; 146baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod 147d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod // The pre-existing content of this view didn't match the current URL. Load the new image 148d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod // from the network. 149d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod ImageContainer newContainer = mImageLoader.get(mUrl, 150b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod new ImageListener() { 151b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod @Override 152b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod public void onErrorResponse(VolleyError error) { 153b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod if (mErrorImageId != 0) { 154b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod setImageResource(mErrorImageId); 155b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod } 156b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod } 157b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod 158b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod @Override 159b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod public void onResponse(final ImageContainer response, boolean isImmediate) { 160b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod // If this was an immediate response that was delivered inside of a layout 161b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod // pass do not set the image immediately as it will trigger a requestLayout 162b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod // inside of a layout. Instead, defer setting the image by posting back to 163b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod // the main thread. 164b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod if (isImmediate && isInLayoutPass) { 165b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod post(new Runnable() { 166b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod @Override 167b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod public void run() { 168b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod onResponse(response, false); 169b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod } 170b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod }); 171b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod return; 172b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod } 173b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod 174b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod if (response.getBitmap() != null) { 175b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod setImageBitmap(response.getBitmap()); 176b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod } else if (mDefaultImageId != 0) { 177b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod setImageResource(mDefaultImageId); 178b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod } 179b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod } 180baa2ff70bea2dbfb89d6732902e6b2bd6de7d207Aurash Mahbod }, maxWidth, maxHeight); 181d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 182da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton // update the ImageContainer to be the new bitmap container. 183da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton mImageContainer = newContainer; 184d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 185d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 18654086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown private void setDefaultImageOrNull() { 18754086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown if(mDefaultImageId != 0) { 18854086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown setImageResource(mDefaultImageId); 18954086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown } 19054086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown else { 19154086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown setImageBitmap(null); 19254086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown } 19354086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown } 19454086f9c87af47015cb5de5356310598e4b7dbf5Adam W. Brown 195d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod @Override 196d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 197d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod super.onLayout(changed, left, top, right, bottom); 198b25a6e0f4d3bfdeddfc10e8f5518bab5c16634fdAurash Mahbod loadImageIfNecessary(true); 199d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 200d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 201d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod @Override 202d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod protected void onDetachedFromWindow() { 203da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton if (mImageContainer != null) { 204d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod // If the view was bound to an image request, cancel it and clear 205d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod // out the image from the view. 206da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton mImageContainer.cancelRequest(); 207d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod setImageBitmap(null); 208da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton // also clear out the container so we can reload the image if necessary. 209da703141dabd9cae3f71e15a4b9cbb79f6d5d4b8Evan Charlton mImageContainer = null; 210d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 211d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod super.onDetachedFromWindow(); 212d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 213d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod 214d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod @Override 215d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod protected void drawableStateChanged() { 216d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod super.drawableStateChanged(); 217d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod invalidate(); 218d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod } 219d62a616ebca5bfa4f9ec5517208e13f2d501b69aAurash Mahbod} 220