Adding browsable prebuilt samples for march push

Change-Id: I952db10d9c9acb4940db08a07789347ea2effe4d
This commit is contained in:
Alexander Lucas
2014-03-07 13:34:45 -08:00
parent 7cd4524c3b
commit a780ba4b15
213 changed files with 15681 additions and 93 deletions

View File

@@ -0,0 +1,213 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.displayingbitmaps.ui;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager.LayoutParams;
import android.widget.Toast;
import com.example.android.displayingbitmaps.BuildConfig;
import com.example.android.displayingbitmaps.R;
import com.example.android.displayingbitmaps.provider.Images;
import com.example.android.displayingbitmaps.util.ImageCache;
import com.example.android.displayingbitmaps.util.ImageFetcher;
import com.example.android.displayingbitmaps.util.Utils;
public class ImageDetailActivity extends FragmentActivity implements OnClickListener {
private static final String IMAGE_CACHE_DIR = "images";
public static final String EXTRA_IMAGE = "extra_image";
private ImagePagerAdapter mAdapter;
private ImageFetcher mImageFetcher;
private ViewPager mPager;
@TargetApi(VERSION_CODES.HONEYCOMB)
@Override
public void onCreate(Bundle savedInstanceState) {
if (BuildConfig.DEBUG) {
Utils.enableStrictMode();
}
super.onCreate(savedInstanceState);
setContentView(R.layout.image_detail_pager);
// Fetch screen height and width, to use as our max size when loading images as this
// activity runs full screen
final DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
final int height = displayMetrics.heightPixels;
final int width = displayMetrics.widthPixels;
// For this sample we'll use half of the longest width to resize our images. As the
// image scaling ensures the image is larger than this, we should be left with a
// resolution that is appropriate for both portrait and landscape. For best image quality
// we shouldn't divide by 2, but this will use more memory and require a larger memory
// cache.
final int longest = (height > width ? height : width) / 2;
ImageCache.ImageCacheParams cacheParams =
new ImageCache.ImageCacheParams(this, IMAGE_CACHE_DIR);
cacheParams.setMemCacheSizePercent(0.25f); // Set memory cache to 25% of app memory
// The ImageFetcher takes care of loading images into our ImageView children asynchronously
mImageFetcher = new ImageFetcher(this, longest);
mImageFetcher.addImageCache(getSupportFragmentManager(), cacheParams);
mImageFetcher.setImageFadeIn(false);
// Set up ViewPager and backing adapter
mAdapter = new ImagePagerAdapter(getSupportFragmentManager(), Images.imageUrls.length);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.setPageMargin((int) getResources().getDimension(R.dimen.horizontal_page_margin));
mPager.setOffscreenPageLimit(2);
// Set up activity to go full screen
getWindow().addFlags(LayoutParams.FLAG_FULLSCREEN);
// Enable some additional newer visibility and ActionBar features to create a more
// immersive photo viewing experience
if (Utils.hasHoneycomb()) {
final ActionBar actionBar = getActionBar();
// Hide title text and set home as up
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
// Hide and show the ActionBar as the visibility changes
mPager.setOnSystemUiVisibilityChangeListener(
new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int vis) {
if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
actionBar.hide();
} else {
actionBar.show();
}
}
});
// Start low profile mode and hide ActionBar
mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
actionBar.hide();
}
// Set the current item based on the extra passed in to this activity
final int extraCurrentItem = getIntent().getIntExtra(EXTRA_IMAGE, -1);
if (extraCurrentItem != -1) {
mPager.setCurrentItem(extraCurrentItem);
}
}
@Override
public void onResume() {
super.onResume();
mImageFetcher.setExitTasksEarly(false);
}
@Override
protected void onPause() {
super.onPause();
mImageFetcher.setExitTasksEarly(true);
mImageFetcher.flushCache();
}
@Override
protected void onDestroy() {
super.onDestroy();
mImageFetcher.closeCache();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
case R.id.clear_cache:
mImageFetcher.clearCache();
Toast.makeText(
this, R.string.clear_cache_complete_toast,Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
/**
* Called by the ViewPager child fragments to load images via the one ImageFetcher
*/
public ImageFetcher getImageFetcher() {
return mImageFetcher;
}
/**
* The main adapter that backs the ViewPager. A subclass of FragmentStatePagerAdapter as there
* could be a large number of items in the ViewPager and we don't want to retain them all in
* memory at once but create/destroy them on the fly.
*/
private class ImagePagerAdapter extends FragmentStatePagerAdapter {
private final int mSize;
public ImagePagerAdapter(FragmentManager fm, int size) {
super(fm);
mSize = size;
}
@Override
public int getCount() {
return mSize;
}
@Override
public Fragment getItem(int position) {
return ImageDetailFragment.newInstance(Images.imageUrls[position]);
}
}
/**
* Set on the ImageView in the ViewPager children fragments, to enable/disable low profile mode
* when the ImageView is touched.
*/
@TargetApi(VERSION_CODES.HONEYCOMB)
@Override
public void onClick(View v) {
final int vis = mPager.getSystemUiVisibility();
if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
} else {
mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
}
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.displayingbitmaps.ui;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.example.android.displayingbitmaps.R;
import com.example.android.displayingbitmaps.util.ImageFetcher;
import com.example.android.displayingbitmaps.util.ImageWorker;
import com.example.android.displayingbitmaps.util.Utils;
/**
* This fragment will populate the children of the ViewPager from {@link ImageDetailActivity}.
*/
public class ImageDetailFragment extends Fragment {
private static final String IMAGE_DATA_EXTRA = "extra_image_data";
private String mImageUrl;
private ImageView mImageView;
private ImageFetcher mImageFetcher;
/**
* Factory method to generate a new instance of the fragment given an image number.
*
* @param imageUrl The image url to load
* @return A new instance of ImageDetailFragment with imageNum extras
*/
public static ImageDetailFragment newInstance(String imageUrl) {
final ImageDetailFragment f = new ImageDetailFragment();
final Bundle args = new Bundle();
args.putString(IMAGE_DATA_EXTRA, imageUrl);
f.setArguments(args);
return f;
}
/**
* Empty constructor as per the Fragment documentation
*/
public ImageDetailFragment() {}
/**
* Populate image using a url from extras, use the convenience factory method
* {@link ImageDetailFragment#newInstance(String)} to create this fragment.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mImageUrl = getArguments() != null ? getArguments().getString(IMAGE_DATA_EXTRA) : null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate and locate the main ImageView
final View v = inflater.inflate(R.layout.image_detail_fragment, container, false);
mImageView = (ImageView) v.findViewById(R.id.imageView);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Use the parent activity to load the image asynchronously into the ImageView (so a single
// cache can be used over all pages in the ViewPager
if (ImageDetailActivity.class.isInstance(getActivity())) {
mImageFetcher = ((ImageDetailActivity) getActivity()).getImageFetcher();
mImageFetcher.loadImage(mImageUrl, mImageView);
}
// Pass clicks on the ImageView to the parent activity to handle
if (OnClickListener.class.isInstance(getActivity()) && Utils.hasHoneycomb()) {
mImageView.setOnClickListener((OnClickListener) getActivity());
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mImageView != null) {
// Cancel any pending image work
ImageWorker.cancelWork(mImageView);
mImageView.setImageDrawable(null);
}
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.displayingbitmaps.ui;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import com.example.android.displayingbitmaps.BuildConfig;
import com.example.android.displayingbitmaps.util.Utils;
/**
* Simple FragmentActivity to hold the main {@link ImageGridFragment} and not much else.
*/
public class ImageGridActivity extends FragmentActivity {
private static final String TAG = "ImageGridActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
if (BuildConfig.DEBUG) {
Utils.enableStrictMode();
}
super.onCreate(savedInstanceState);
if (getSupportFragmentManager().findFragmentByTag(TAG) == null) {
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(android.R.id.content, new ImageGridFragment(), TAG);
ft.commit();
}
}
}

View File

@@ -0,0 +1,336 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.displayingbitmaps.ui;
import android.annotation.TargetApi;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.android.common.logger.Log;
import com.example.android.displayingbitmaps.BuildConfig;
import com.example.android.displayingbitmaps.R;
import com.example.android.displayingbitmaps.provider.Images;
import com.example.android.displayingbitmaps.util.ImageCache;
import com.example.android.displayingbitmaps.util.ImageFetcher;
import com.example.android.displayingbitmaps.util.Utils;
/**
* The main fragment that powers the ImageGridActivity screen. Fairly straight forward GridView
* implementation with the key addition being the ImageWorker class w/ImageCache to load children
* asynchronously, keeping the UI nice and smooth and caching thumbnails for quick retrieval. The
* cache is retained over configuration changes like orientation change so the images are populated
* quickly if, for example, the user rotates the device.
*/
public class ImageGridFragment extends Fragment implements AdapterView.OnItemClickListener {
private static final String TAG = "ImageGridFragment";
private static final String IMAGE_CACHE_DIR = "thumbs";
private int mImageThumbSize;
private int mImageThumbSpacing;
private ImageAdapter mAdapter;
private ImageFetcher mImageFetcher;
/**
* Empty constructor as per the Fragment documentation
*/
public ImageGridFragment() {}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mImageThumbSize = getResources().getDimensionPixelSize(R.dimen.image_thumbnail_size);
mImageThumbSpacing = getResources().getDimensionPixelSize(R.dimen.image_thumbnail_spacing);
mAdapter = new ImageAdapter(getActivity());
ImageCache.ImageCacheParams cacheParams =
new ImageCache.ImageCacheParams(getActivity(), IMAGE_CACHE_DIR);
cacheParams.setMemCacheSizePercent(0.25f); // Set memory cache to 25% of app memory
// The ImageFetcher takes care of loading images into our ImageView children asynchronously
mImageFetcher = new ImageFetcher(getActivity(), mImageThumbSize);
mImageFetcher.setLoadingImage(R.drawable.empty_photo);
mImageFetcher.addImageCache(getActivity().getSupportFragmentManager(), cacheParams);
}
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.image_grid_fragment, container, false);
final GridView mGridView = (GridView) v.findViewById(R.id.gridView);
mGridView.setAdapter(mAdapter);
mGridView.setOnItemClickListener(this);
mGridView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
// Pause fetcher to ensure smoother scrolling when flinging
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
// Before Honeycomb pause image loading on scroll to help with performance
if (!Utils.hasHoneycomb()) {
mImageFetcher.setPauseWork(true);
}
} else {
mImageFetcher.setPauseWork(false);
}
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
});
// This listener is used to get the final width of the GridView and then calculate the
// number of columns and the width of each column. The width of each column is variable
// as the GridView has stretchMode=columnWidth. The column width is used to set the height
// of each view so we get nice square thumbnails.
mGridView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@TargetApi(VERSION_CODES.JELLY_BEAN)
@Override
public void onGlobalLayout() {
if (mAdapter.getNumColumns() == 0) {
final int numColumns = (int) Math.floor(
mGridView.getWidth() / (mImageThumbSize + mImageThumbSpacing));
if (numColumns > 0) {
final int columnWidth =
(mGridView.getWidth() / numColumns) - mImageThumbSpacing;
mAdapter.setNumColumns(numColumns);
mAdapter.setItemHeight(columnWidth);
if (BuildConfig.DEBUG) {
Log.d(TAG, "onCreateView - numColumns set to " + numColumns);
}
if (Utils.hasJellyBean()) {
mGridView.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
} else {
mGridView.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
}
}
}
});
return v;
}
@Override
public void onResume() {
super.onResume();
mImageFetcher.setExitTasksEarly(false);
mAdapter.notifyDataSetChanged();
}
@Override
public void onPause() {
super.onPause();
mImageFetcher.setPauseWork(false);
mImageFetcher.setExitTasksEarly(true);
mImageFetcher.flushCache();
}
@Override
public void onDestroy() {
super.onDestroy();
mImageFetcher.closeCache();
}
@TargetApi(VERSION_CODES.JELLY_BEAN)
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
final Intent i = new Intent(getActivity(), ImageDetailActivity.class);
i.putExtra(ImageDetailActivity.EXTRA_IMAGE, (int) id);
if (Utils.hasJellyBean()) {
// makeThumbnailScaleUpAnimation() looks kind of ugly here as the loading spinner may
// show plus the thumbnail image in GridView is cropped. so using
// makeScaleUpAnimation() instead.
ActivityOptions options =
ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getWidth(), v.getHeight());
getActivity().startActivity(i, options.toBundle());
} else {
startActivity(i);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.clear_cache:
mImageFetcher.clearCache();
Toast.makeText(getActivity(), R.string.clear_cache_complete_toast,
Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* The main adapter that backs the GridView. This is fairly standard except the number of
* columns in the GridView is used to create a fake top row of empty views as we use a
* transparent ActionBar and don't want the real top row of images to start off covered by it.
*/
private class ImageAdapter extends BaseAdapter {
private final Context mContext;
private int mItemHeight = 0;
private int mNumColumns = 0;
private int mActionBarHeight = 0;
private GridView.LayoutParams mImageViewLayoutParams;
public ImageAdapter(Context context) {
super();
mContext = context;
mImageViewLayoutParams = new GridView.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
// Calculate ActionBar height
TypedValue tv = new TypedValue();
if (context.getTheme().resolveAttribute(
android.R.attr.actionBarSize, tv, true)) {
mActionBarHeight = TypedValue.complexToDimensionPixelSize(
tv.data, context.getResources().getDisplayMetrics());
}
}
@Override
public int getCount() {
// If columns have yet to be determined, return no items
if (getNumColumns() == 0) {
return 0;
}
// Size + number of columns for top empty row
return Images.imageThumbUrls.length + mNumColumns;
}
@Override
public Object getItem(int position) {
return position < mNumColumns ?
null : Images.imageThumbUrls[position - mNumColumns];
}
@Override
public long getItemId(int position) {
return position < mNumColumns ? 0 : position - mNumColumns;
}
@Override
public int getViewTypeCount() {
// Two types of views, the normal ImageView and the top row of empty views
return 2;
}
@Override
public int getItemViewType(int position) {
return (position < mNumColumns) ? 1 : 0;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getView(int position, View convertView, ViewGroup container) {
//BEGIN_INCLUDE(load_gridview_item)
// First check if this is the top row
if (position < mNumColumns) {
if (convertView == null) {
convertView = new View(mContext);
}
// Set empty view with height of ActionBar
convertView.setLayoutParams(new AbsListView.LayoutParams(
LayoutParams.MATCH_PARENT, mActionBarHeight));
return convertView;
}
// Now handle the main ImageView thumbnails
ImageView imageView;
if (convertView == null) { // if it's not recycled, instantiate and initialize
imageView = new RecyclingImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(mImageViewLayoutParams);
} else { // Otherwise re-use the converted view
imageView = (ImageView) convertView;
}
// Check the height matches our calculated column width
if (imageView.getLayoutParams().height != mItemHeight) {
imageView.setLayoutParams(mImageViewLayoutParams);
}
// Finally load the image asynchronously into the ImageView, this also takes care of
// setting a placeholder image while the background thread runs
mImageFetcher.loadImage(Images.imageThumbUrls[position - mNumColumns], imageView);
return imageView;
//END_INCLUDE(load_gridview_item)
}
/**
* Sets the item height. Useful for when we know the column width so the height can be set
* to match.
*
* @param height
*/
public void setItemHeight(int height) {
if (height == mItemHeight) {
return;
}
mItemHeight = height;
mImageViewLayoutParams =
new GridView.LayoutParams(LayoutParams.MATCH_PARENT, mItemHeight);
mImageFetcher.setImageSize(height);
notifyDataSetChanged();
}
public void setNumColumns(int numColumns) {
mNumColumns = numColumns;
}
public int getNumColumns() {
return mNumColumns;
}
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.displayingbitmaps.ui;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.example.android.displayingbitmaps.util.RecyclingBitmapDrawable;
/**
* Sub-class of ImageView which automatically notifies the drawable when it is
* being displayed.
*/
public class RecyclingImageView extends ImageView {
public RecyclingImageView(Context context) {
super(context);
}
public RecyclingImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* @see android.widget.ImageView#onDetachedFromWindow()
*/
@Override
protected void onDetachedFromWindow() {
// This has been detached from Window, so clear the drawable
setImageDrawable(null);
super.onDetachedFromWindow();
}
/**
* @see android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)
*/
@Override
public void setImageDrawable(Drawable drawable) {
// Keep hold of previous Drawable
final Drawable previousDrawable = getDrawable();
// Call super to set new Drawable
super.setImageDrawable(drawable);
// Notify new Drawable that it is being displayed
notifyDrawable(drawable, true);
// Notify old Drawable so it is no longer being displayed
notifyDrawable(previousDrawable, false);
}
/**
* Notifies the drawable that it's displayed state has changed.
*
* @param drawable
* @param isDisplayed
*/
private static void notifyDrawable(Drawable drawable, final boolean isDisplayed) {
if (drawable instanceof RecyclingBitmapDrawable) {
// The drawable is a CountingBitmapDrawable, so notify it
((RecyclingBitmapDrawable) drawable).setIsDisplayed(isDisplayed);
} else if (drawable instanceof LayerDrawable) {
// The drawable is a LayerDrawable, so recurse on each layer
LayerDrawable layerDrawable = (LayerDrawable) drawable;
for (int i = 0, z = layerDrawable.getNumberOfLayers(); i < z; i++) {
notifyDrawable(layerDrawable.getDrawable(i), isDisplayed);
}
}
}
}