Loading previews and holographic icons in background thread using AsyncTasks.

- Adding back animation between tabs

Change-Id: I1a49bfca4f85f579e232861aa02d08fb25d0aafc
This commit is contained in:
Winson Chung
2011-06-13 11:32:14 -07:00
parent 4b825dcd5f
commit b44b52439d
10 changed files with 449 additions and 358 deletions
@@ -33,11 +33,15 @@ import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Process;
import android.util.AttributeSet;
import android.util.Log;
import android.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -54,6 +58,99 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* A simple callback interface which also provides the results of the task.
*/
interface AsyncTaskCallback {
void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data);
}
/**
* The data needed to perform either of the custom AsyncTasks.
*/
class AsyncTaskPageData {
AsyncTaskPageData(int p, ArrayList<Object> l, ArrayList<Bitmap> si, AsyncTaskCallback bgR,
AsyncTaskCallback postR) {
page = p;
items = l;
srcImages = si;
images = new ArrayList<Bitmap>();
cellWidth = cellHeight = -1;
doInBackgroundCallback = bgR;
postExecuteCallback = postR;
}
AsyncTaskPageData(int p, ArrayList<Object> l, int cw, int ch, AsyncTaskCallback bgR,
AsyncTaskCallback postR) {
page = p;
items = l;
images = new ArrayList<Bitmap>();
cellWidth = cw;
cellHeight = ch;
doInBackgroundCallback = bgR;
postExecuteCallback = postR;
}
int page;
ArrayList<Object> items;
ArrayList<Bitmap> srcImages;
ArrayList<Bitmap> images;
int cellWidth;
int cellHeight;
AsyncTaskCallback doInBackgroundCallback;
AsyncTaskCallback postExecuteCallback;
}
/**
* A generic template for an async task used in AppsCustomize.
*/
class AppsCustomizeAsyncTask extends AsyncTask<AsyncTaskPageData, Void, AsyncTaskPageData> {
AppsCustomizeAsyncTask(int p, AppsCustomizePagedView.ContentType t) {
page = p;
pageContentType = t;
threadPriority = Process.THREAD_PRIORITY_DEFAULT;
}
@Override
protected AsyncTaskPageData doInBackground(AsyncTaskPageData... params) {
if (params.length != 1) return null;
// Load each of the widget previews in the background
params[0].doInBackgroundCallback.run(this, params[0]);
return params[0];
}
@Override
protected void onPostExecute(AsyncTaskPageData result) {
// All the widget previews are loaded, so we can just callback to inflate the page
result.postExecuteCallback.run(this, result);
}
void setThreadPriority(int p) {
threadPriority = p;
}
void syncThreadPriority() {
Process.setThreadPriority(threadPriority);
}
// The page that this async task is associated with
int page;
AppsCustomizePagedView.ContentType pageContentType;
int threadPriority;
}
/**
* An AsyncTask that loads widget previews from package manager in the background.
*/
class LoadWidgetPreviewsTask extends AppsCustomizeAsyncTask {
LoadWidgetPreviewsTask(int p, AppsCustomizePagedView.ContentType t) {
super(p, t);
}
}
/**
* An AsyncTask that generates holgoraphic outlines for a specified set of bitmaps.
*/
class GenerateHoloOutlinesTask extends AppsCustomizeAsyncTask {
GenerateHoloOutlinesTask(int p, AppsCustomizePagedView.ContentType t) {
super(p, t);
}
}
/**
* The Apps/Customize page that displays all the applications, widgets, and shortcuts.
*/
public class AppsCustomizePagedView extends PagedViewWithDraggableItems implements
AllAppsView, View.OnClickListener, DragSource {
static final String LOG_TAG = "AppsCustomizePagedView";
@@ -78,9 +175,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
private List<Object> mWidgets;
// Caching
private Canvas mCanvas;
private Drawable mDefaultWidgetBackground;
private final int sWidgetPreviewCacheSize = 1 * 1024 * 1024; // 1 MiB
private LruCache<Object, Bitmap> mWidgetPreviewCache;
private IconCache mIconCache;
// Dimens
@@ -92,10 +188,9 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
private final float sWidgetPreviewIconPaddingPercentage = 0.25f;
private PagedViewCellLayout mWidgetSpacingLayout;
// Animations
private final float ANIMATION_SCALE = 0.5f;
private final int TRANSLATE_ANIM_DURATION = 400;
private final int DROP_ANIM_DURATION = 200;
// Previews & outlines
ArrayList<AppsCustomizeAsyncTask> mRunningTasks;
private HolographicOutlineHelper mHolographicOutlineHelper;
public AppsCustomizePagedView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -105,11 +200,9 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
mApps = new ArrayList<ApplicationInfo>();
mWidgets = new ArrayList<Object>();
mIconCache = ((LauncherApplication) context.getApplicationContext()).getIconCache();
mWidgetPreviewCache = new LruCache<Object, Bitmap>(sWidgetPreviewCacheSize) {
protected int sizeOf(Object key, Bitmap value) {
return value.getByteCount();
}
};
mHolographicOutlineHelper = new HolographicOutlineHelper();
mCanvas = new Canvas();
mRunningTasks = new ArrayList<AppsCustomizeAsyncTask>();
// Save the default widget preview background
Resources resources = context.getResources();
@@ -288,9 +381,11 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
final Drawable icon = tv.getCompoundDrawables()[1];
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
c.translate((v.getWidth() - icon.getIntrinsicWidth()) / 2, v.getPaddingTop());
icon.draw(c);
mCanvas.setBitmap(b);
mCanvas.save();
mCanvas.translate((v.getWidth() - icon.getIntrinsicWidth()) / 2, v.getPaddingTop());
icon.draw(mCanvas);
mCanvas.restore();
// Compose the visible rect of the drag image
Rect dragRect = null;
@@ -334,8 +429,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
// the shortcut icon) to a new drag bitmap that clips the non-icon space.
b = Bitmap.createBitmap(mWidgetPreviewIconPaddedDimension,
mWidgetPreviewIconPaddedDimension, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
preview.draw(c);
mCanvas.setBitmap(b);
mCanvas.save();
preview.draw(mCanvas);
mCanvas.restore();
createItemInfo.spanX = createItemInfo.spanY = 1;
}
@@ -424,6 +521,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
invalidatePageData();
}
public boolean isContentType(ContentType type) {
return (mContentType == type);
}
/*
* Apps PagedView implementation
*/
@@ -468,12 +569,13 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
int endIndex = Math.min(startIndex + numCells, mApps.size());
PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(page);
layout.removeAllViewsOnPage();
ArrayList<Object> items = new ArrayList<Object>();
ArrayList<Bitmap> images = new ArrayList<Bitmap>();
for (int i = startIndex; i < endIndex; ++i) {
ApplicationInfo info = mApps.get(i);
PagedViewIcon icon = (PagedViewIcon) mLayoutInflater.inflate(
R.layout.apps_customize_application, layout, false);
icon.applyFromApplicationInfo(
info, mPageViewIconCache, true, (numPages > 1));
icon.applyFromApplicationInfo(info, true, mHolographicOutlineHelper);
icon.setOnClickListener(this);
icon.setOnLongClickListener(this);
icon.setOnTouchListener(this);
@@ -482,12 +584,155 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
int x = index % mCellCountX;
int y = index / mCellCountX;
layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
items.add(info);
images.add(info.iconBitmap);
}
// Create the hardware layers
layout.allowHardwareLayerCreation();
layout.createHardwareLayers();
prepareGenerateHoloOutlinesTask(page, items, images);
}
/**
* Return the appropriate thread priority for loading for a given page (we give the current
* page much higher priority)
*/
private int getThreadPriorityForPage(int page) {
// TODO-APPS_CUSTOMIZE: detect number of cores and set thread priorities accordingly below
int pageDiff = Math.abs(page - mCurrentPage);
if (pageDiff <= 0) {
// return Process.THREAD_PRIORITY_DEFAULT;
return Process.THREAD_PRIORITY_MORE_FAVORABLE;
} else if (pageDiff <= 1) {
// return Process.THREAD_PRIORITY_BACKGROUND;
return Process.THREAD_PRIORITY_DEFAULT;
} else {
// return Process.THREAD_PRIORITY_LOWEST;
return Process.THREAD_PRIORITY_DEFAULT;
}
}
/**
* Creates and executes a new AsyncTask to load a page of widget previews.
*/
private void prepareLoadWidgetPreviewsTask(int page, ArrayList<Object> widgets,
int cellWidth, int cellHeight) {
// Prune all tasks that are no longer needed
Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
while (iter.hasNext()) {
AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
int taskPage = task.page;
if (taskPage < (mCurrentPage - 2) || taskPage > (mCurrentPage + 2)) {
task.cancel(false);
iter.remove();
} else {
task.setThreadPriority(getThreadPriorityForPage(taskPage));
}
}
AsyncTaskPageData pageData = new AsyncTaskPageData(page, widgets, cellWidth, cellHeight,
new AsyncTaskCallback() {
@Override
public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
// Ensure that this task starts running at the correct priority
task.syncThreadPriority();
// Load each of the widget/shortcut previews
ArrayList<Object> items = data.items;
ArrayList<Bitmap> images = data.images;
int count = items.size();
int cellWidth = data.cellWidth;
int cellHeight = data.cellHeight;
for (int i = 0; i < count && !task.isCancelled(); ++i) {
// Before work on each item, ensure that this task is running at the correct
// priority
task.syncThreadPriority();
Object rawInfo = items.get(i);
if (rawInfo instanceof AppWidgetProviderInfo) {
AppWidgetProviderInfo info = (AppWidgetProviderInfo) rawInfo;
int[] cellSpans = CellLayout.rectToCell(getResources(),
info.minWidth, info.minHeight, null);
images.add(getWidgetPreviewInBackground(info, cellSpans[0],cellSpans[1],
cellWidth, cellHeight));
} else if (rawInfo instanceof ResolveInfo) {
// Fill in the shortcuts information
ResolveInfo info = (ResolveInfo) rawInfo;
images.add(getShortcutPreviewInBackground(info, cellWidth, cellHeight));
}
}
}
},
new AsyncTaskCallback() {
@Override
public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
mRunningTasks.remove(task);
if (task.page > getPageCount()) return;
if (task.pageContentType != mContentType) return;
onSyncWidgetPageItems(data);
}
});
// Ensure that the task is appropriately prioritized and runs in parallel
LoadWidgetPreviewsTask t = new LoadWidgetPreviewsTask(page, mContentType);
t.setThreadPriority(getThreadPriorityForPage(page));
t.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, pageData);
mRunningTasks.add(t);
}
/**
* Creates and executes a new AsyncTask to load the outlines for a page of content.
*/
private void prepareGenerateHoloOutlinesTask(int page, ArrayList<Object> items,
ArrayList<Bitmap> images) {
AsyncTaskPageData pageData = new AsyncTaskPageData(page, items, images,
new AsyncTaskCallback() {
@Override
public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
// Ensure that this task starts running at the correct priority
task.syncThreadPriority();
ArrayList<Bitmap> images = data.images;
ArrayList<Bitmap> srcImages = data.srcImages;
int count = srcImages.size();
Canvas c = new Canvas();
for (int i = 0; i < count && !task.isCancelled(); ++i) {
// Before work on each item, ensure that this task is running at the correct
// priority
task.syncThreadPriority();
Bitmap b = srcImages.get(i);
Bitmap outline = Bitmap.createBitmap(b.getWidth(), b.getHeight(),
Bitmap.Config.ARGB_8888);
c.setBitmap(outline);
c.save();
c.drawBitmap(b, 0, 0, null);
c.restore();
images.add(outline);
}
}
},
new AsyncTaskCallback() {
@Override
public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
mRunningTasks.remove(task);
if (task.page > getPageCount()) return;
if (task.pageContentType != mContentType) return;
onHolographicPageItemsLoaded(data);
}
});
// Ensure that the outline task always runs in the background, serially
GenerateHoloOutlinesTask t =
new GenerateHoloOutlinesTask(page, mContentType);
t.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
t.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, pageData);
mRunningTasks.add(t);
}
/*
* Widgets PagedView implementation
*/
@@ -506,27 +751,19 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
layout.measure(widthSpec, heightSpec);
setVisibilityOnChildren(layout, View.VISIBLE);
}
private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h,
private synchronized void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h,
float scaleX, float scaleY) {
if (bitmap != null) {
Canvas c = new Canvas();
c.setBitmap(bitmap);
c.save();
Canvas c = new Canvas(bitmap);
c.scale(scaleX, scaleY);
Rect oldBounds = d.copyBounds();
d.setBounds(x, y, x + w, y + h);
d.draw(c);
d.setBounds(oldBounds); // Restore the bounds
c.restore();
}
}
private FastBitmapDrawable getShortcutPreview(ResolveInfo info, int cellWidth, int cellHeight) {
// Return the cached version if necessary
Bitmap cachedBitmap = mWidgetPreviewCache.get(info);
if (cachedBitmap != null) {
return new FastBitmapDrawable(cachedBitmap);
}
private Bitmap getShortcutPreviewInBackground(ResolveInfo info, int cellWidth,
int cellHeight) {
Resources resources = mLauncher.getResources();
int iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
// We only need to make it wide enough so as not allow the preview to be scaled
@@ -537,18 +774,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
Bitmap preview = Bitmap.createBitmap(expectedWidth, expectedHeight, Config.ARGB_8888);
Drawable icon = mIconCache.getFullResIcon(info, mPackageManager);
renderDrawableToBitmap(icon, preview, 0, 0, iconSize, iconSize, 1f, 1f);
FastBitmapDrawable iconDrawable = new FastBitmapDrawable(preview);
iconDrawable.setBounds(0, 0, expectedWidth, expectedHeight);
mWidgetPreviewCache.put(info, preview);
return iconDrawable;
return preview;
}
private FastBitmapDrawable getWidgetPreview(AppWidgetProviderInfo info, int cellHSpan,
int cellVSpan, int cellWidth, int cellHeight) {
// Return the cached version if necessary
Bitmap cachedBitmap = mWidgetPreviewCache.get(info);
if (cachedBitmap != null) {
return new FastBitmapDrawable(cachedBitmap);
}
private Bitmap getWidgetPreviewInBackground(AppWidgetProviderInfo info,
int cellHSpan, int cellVSpan, int cellWidth, int cellHeight) {
// Calculate the size of the drawable
cellHSpan = Math.max(mMinWidgetSpan, Math.min(mMaxWidgetSpan, cellHSpan));
@@ -564,7 +793,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
// Load the preview image if possible
String packageName = info.provider.getPackageName();
Drawable drawable = null;
FastBitmapDrawable newDrawable = null;
Bitmap preview = null;
if (info.previewImage != 0) {
drawable = mPackageManager.getDrawable(packageName, info.previewImage, null);
if (drawable == null) {
@@ -585,11 +814,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
newWidth = (int) (imageWidth * ((float) expectedHeight / imageHeight));
}
Bitmap preview = Bitmap.createBitmap(newWidth, newHeight, Config.ARGB_8888);
preview = Bitmap.createBitmap(newWidth, newHeight, Config.ARGB_8888);
renderDrawableToBitmap(drawable, preview, 0, 0, newWidth, newHeight, 1f, 1f);
newDrawable = new FastBitmapDrawable(preview);
newDrawable.setBounds(0, 0, newWidth, newHeight);
mWidgetPreviewCache.put(info, preview);
}
}
@@ -609,7 +835,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
expectedHeight = cellWidth;
}
Bitmap preview = Bitmap.createBitmap(expectedWidth, expectedHeight, Config.ARGB_8888);
preview = Bitmap.createBitmap(expectedWidth, expectedHeight, Config.ARGB_8888);
renderDrawableToBitmap(mDefaultWidgetBackground, preview, 0, 0, expectedWidth,
expectedHeight, 1f,1f);
@@ -622,12 +848,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
int offset = (int) (iconSize * sWidgetPreviewIconPaddingPercentage);
renderDrawableToBitmap(icon, preview, offset, offset, iconSize, iconSize, 1f, 1f);
} catch (Resources.NotFoundException e) {}
newDrawable = new FastBitmapDrawable(preview);
newDrawable.setBounds(0, 0, expectedWidth, expectedHeight);
mWidgetPreviewCache.put(info, preview);
}
return newDrawable;
return preview;
}
public void syncWidgetPages() {
// Ensure that we have the right number of pages
@@ -642,19 +864,34 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
}
}
public void syncWidgetPageItems(int page) {
// Calculate the dimensions of each cell we are giving to each widget
ArrayList<Object> widgets = new ArrayList<Object>();
int cellWidth = ((mWidgetSpacingLayout.getContentWidth()
- mPageLayoutPaddingLeft - mPageLayoutPaddingRight
- ((mWidgetCountX - 1) * mWidgetWidthGap)) / mWidgetCountX);
int cellHeight = ((mWidgetSpacingLayout.getContentHeight()
- mPageLayoutPaddingTop - mPageLayoutPaddingBottom
- ((mWidgetCountY - 1) * mWidgetHeightGap)) / mWidgetCountY);
int numWidgetsPerPage = mWidgetCountX * mWidgetCountY;
int offset = page * numWidgetsPerPage;
for (int i = offset; i < Math.min(offset + numWidgetsPerPage, mWidgets.size()); ++i) {
widgets.add(mWidgets.get(i));
}
prepareLoadWidgetPreviewsTask(page, widgets, cellWidth, cellHeight);
}
private void onSyncWidgetPageItems(AsyncTaskPageData data) {
int page = data.page;
PagedViewGridLayout layout = (PagedViewGridLayout) getChildAt(page);
layout.removeAllViews();
// Calculate the dimensions of each cell we are giving to each widget
int numWidgetsPerPage = mWidgetCountX * mWidgetCountY;
int numPages = (int) Math.ceil(mWidgets.size() / (float) numWidgetsPerPage);
int offset = page * numWidgetsPerPage;
int cellWidth = ((mWidgetSpacingLayout.getContentWidth() - mPageLayoutWidthGap
- ((mWidgetCountX - 1) * mWidgetWidthGap)) / mWidgetCountX);
int cellHeight = ((mWidgetSpacingLayout.getContentHeight() - mPageLayoutHeightGap
- ((mWidgetCountY - 1) * mWidgetHeightGap)) / mWidgetCountY);
for (int i = 0; i < Math.min(numWidgetsPerPage, mWidgets.size() - offset); ++i) {
Object rawInfo = mWidgets.get(offset + i);
ArrayList<Object> items = data.items;
int count = items.size();
int cellWidth = data.cellWidth;
int cellHeight = data.cellHeight;
for (int i = 0; i < count; ++i) {
Object rawInfo = items.get(i);
PendingAddItemInfo createItemInfo = null;
PagedViewWidget widget = (PagedViewWidget) mLayoutInflater.inflate(
R.layout.apps_customize_widget, layout, false);
@@ -662,12 +899,11 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
// Fill in the widget information
AppWidgetProviderInfo info = (AppWidgetProviderInfo) rawInfo;
createItemInfo = new PendingAddWidgetInfo(info, null, null);
final int[] cellSpans = CellLayout.rectToCell(getResources(), info.minWidth,
info.minHeight, null);
FastBitmapDrawable preview = getWidgetPreview(info, cellSpans[0], cellSpans[1],
cellWidth, cellHeight);
int[] cellSpans = CellLayout.rectToCell(getResources(),
info.minWidth, info.minHeight, null);
FastBitmapDrawable preview = new FastBitmapDrawable(data.images.get(i));
widget.applyFromAppWidgetProviderInfo(info, preview, -1, cellSpans,
mPageViewIconCache, (numPages > 1));
mHolographicOutlineHelper);
widget.setTag(createItemInfo);
} else if (rawInfo instanceof ResolveInfo) {
// Fill in the shortcuts information
@@ -676,9 +912,9 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
createItemInfo.componentName = new ComponentName(info.activityInfo.packageName,
info.activityInfo.name);
FastBitmapDrawable preview = getShortcutPreview(info, cellWidth, cellHeight);
widget.applyFromResolveInfo(mPackageManager, info, preview, mPageViewIconCache,
(numPages > 1));
FastBitmapDrawable preview = new FastBitmapDrawable(data.images.get(i));
widget.applyFromResolveInfo(mPackageManager, info, preview,
mHolographicOutlineHelper);
widget.setTag(createItemInfo);
}
widget.setOnClickListener(this);
@@ -694,6 +930,31 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
lp.topMargin = (iy * cellHeight) + (iy * mWidgetHeightGap);
layout.addView(widget, lp);
}
invalidate();
forceUpdateAdjacentPagesAlpha();
prepareGenerateHoloOutlinesTask(data.page, data.items, data.images);
}
private void onHolographicPageItemsLoaded(AsyncTaskPageData data) {
// Invalidate early to short-circuit children invalidates
invalidate();
int page = data.page;
ViewGroup layout = (ViewGroup) getChildAt(page);
if (layout instanceof PagedViewCellLayout) {
PagedViewCellLayout cl = (PagedViewCellLayout) layout;
int count = cl.getPageChildCount();
for (int i = 0; i < count; ++i) {
PagedViewIcon icon = (PagedViewIcon) cl.getChildOnPageAt(i);
icon.setHolographicOutline(data.images.get(i));
}
} else {
int count = layout.getChildCount();
for (int i = 0; i < count; ++i) {
View v = layout.getChildAt(i);
((PagedViewWidget) v).setHolographicOutline(data.images.get(i));
}
}
}
@Override
@@ -820,7 +1081,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
int removeIndex = findAppByComponent(mApps, info);
if (removeIndex > -1) {
mApps.remove(removeIndex);
mPageViewIconCache.removeOutline(new PagedViewIconCache.Key(info));
}
}
}
@@ -883,4 +1143,16 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
protected int getPageWidthForScrollingIndicator() {
return getPageContentWidth();
}
/*
* We load an extra page on each side to prevent flashes from scrolling and loading of the
* widget previews in the background with the AsyncTasks.
*/
protected int getAssociatedLowerPageBound(int page) {
return Math.max(0, page - 2);
}
protected int getAssociatedUpperPageBound(int page) {
final int count = getChildCount();
return Math.min(page + 2, count - 1);
}
}