Loading previews and holographic icons in background thread using AsyncTasks.
- Adding back animation between tabs
Change-Id: I1a49bfca4f85f579e232861aa02d08fb25d0aafc
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index c27e375..1d7b34d 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -33,11 +33,15 @@
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.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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
invalidatePageData();
}
+ public boolean isContentType(ContentType type) {
+ return (mContentType == type);
+ }
+
/*
* Apps PagedView implementation
*/
@@ -468,12 +569,13 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 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 @@
// 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 @@
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 @@
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 @@
int removeIndex = findAppByComponent(mApps, info);
if (removeIndex > -1) {
mApps.remove(removeIndex);
- mPageViewIconCache.removeOutline(new PagedViewIconCache.Key(info));
}
}
}
@@ -883,4 +1143,16 @@
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);
+ }
}