diff options
author | Winson Chung <winsonc@google.com> | 2011-06-13 11:32:14 -0700 |
---|---|---|
committer | Winson Chung <winsonc@google.com> | 2011-06-23 11:26:17 -0700 |
commit | b44b52439d155f570db7d6d0b80fdd3350e35685 (patch) | |
tree | d07c95c4a43b7bfb1504b1a521e097f238f6eb77 /src/com/android | |
parent | 4b825dcd5f64a5ebb60271844fbc5257374422bc (diff) | |
download | android_packages_apps_Trebuchet-b44b52439d155f570db7d6d0b80fdd3350e35685.tar.gz android_packages_apps_Trebuchet-b44b52439d155f570db7d6d0b80fdd3350e35685.tar.bz2 android_packages_apps_Trebuchet-b44b52439d155f570db7d6d0b80fdd3350e35685.zip |
Loading previews and holographic icons in background thread using AsyncTasks.
- Adding back animation between tabs
Change-Id: I1a49bfca4f85f579e232861aa02d08fb25d0aafc
Diffstat (limited to 'src/com/android')
-rw-r--r-- | src/com/android/launcher2/AllAppsPagedView.java | 8 | ||||
-rw-r--r-- | src/com/android/launcher2/AppsCustomizePagedView.java | 418 | ||||
-rw-r--r-- | src/com/android/launcher2/AppsCustomizeTabHost.java | 24 | ||||
-rw-r--r-- | src/com/android/launcher2/CustomizePagedView.java | 32 | ||||
-rw-r--r-- | src/com/android/launcher2/HolographicOutlineHelper.java | 6 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedView.java | 24 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedViewCellLayout.java | 13 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedViewCellLayoutChildren.java | 22 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedViewIcon.java | 112 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedViewWidget.java | 150 |
10 files changed, 450 insertions, 359 deletions
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java index 5c8812df3..b3136e620 100644 --- a/src/com/android/launcher2/AllAppsPagedView.java +++ b/src/com/android/launcher2/AllAppsPagedView.java @@ -462,7 +462,6 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All mApps = list; Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR); mFilteredApps = rebuildFilteredApps(mApps); - mPageViewIconCache.retainAllApps(list); invalidatePageData(); } @@ -509,7 +508,6 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All int removeIndex = findAppByComponent(mApps, info); if (removeIndex > -1) { mApps.remove(removeIndex); - mPageViewIconCache.removeOutline(new PagedViewIconCache.Key(info)); } } mFilteredApps = rebuildFilteredApps(mApps); @@ -576,6 +574,7 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All @Override public void syncPages() { + /* // ensure that we have the right number of pages (min of 1, since we have placeholders) int numPages = Math.max(1, (int) Math.ceil((float) mFilteredApps.size() / (mCellCountX * mCellCountY))); @@ -597,10 +596,12 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All // bound the current page setCurrentPage(Math.max(0, Math.min(numPages - 1, getCurrentPage()))); + */ } @Override public void syncPageItems(int page) { + /* // Ensure that we have the right number of items on the pages final int numPages = getPageCount(); final int cellsPerPage = mCellCountX * mCellCountY; @@ -652,7 +653,7 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All final ApplicationInfo info = mFilteredApps.get(i); PagedViewIcon icon = (PagedViewIcon) layout.getChildOnPageAt(index); icon.applyFromApplicationInfo( - info, mPageViewIconCache, true, createHolographicOutlines); + info, null, true, createHolographicOutlines); PagedViewCellLayout.LayoutParams params = (PagedViewCellLayout.LayoutParams) icon.getLayoutParams(); @@ -684,6 +685,7 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All new PagedViewCellLayout.LayoutParams(0, 0, 4, 1)); } layout.createHardwareLayers(); + */ } /* diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java index c27e3759d..1d7b34d68 100644 --- a/src/com/android/launcher2/AppsCustomizePagedView.java +++ b/src/com/android/launcher2/AppsCustomizePagedView.java @@ -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; - } - 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); - } + return preview; + } + 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) { - 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 + ArrayList<Object> widgets = new ArrayList<Object>(); + int cellWidth = ((mWidgetSpacingLayout.getContentWidth() + - mPageLayoutPaddingLeft - mPageLayoutPaddingRight - ((mWidgetCountX - 1) * mWidgetWidthGap)) / mWidgetCountX); - int cellHeight = ((mWidgetSpacingLayout.getContentHeight() - mPageLayoutHeightGap + int cellHeight = ((mWidgetSpacingLayout.getContentHeight() + - mPageLayoutPaddingTop - mPageLayoutPaddingBottom - ((mWidgetCountY - 1) * mWidgetHeightGap)) / mWidgetCountY); - for (int i = 0; i < Math.min(numWidgetsPerPage, mWidgets.size() - offset); ++i) { - Object rawInfo = mWidgets.get(offset + i); + + 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(); + + 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); + } } diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java index 51db66c73..87c154b47 100644 --- a/src/com/android/launcher2/AppsCustomizeTabHost.java +++ b/src/com/android/launcher2/AppsCustomizeTabHost.java @@ -17,6 +17,8 @@ package com.android.launcher2; import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; import android.content.Context; import android.content.res.Resources; import android.util.AttributeSet; @@ -24,6 +26,7 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewPropertyAnimator; import android.widget.TabHost; import android.widget.TabWidget; import android.widget.TextView; @@ -121,7 +124,26 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona @Override public void onTabChanged(String tabId) { - mAppsCustomizePane.setContentType(getContentTypeForTabTag(tabId)); + final AppsCustomizePagedView.ContentType type = getContentTypeForTabTag(tabId); + if (!mAppsCustomizePane.isContentType(type)) { + // Animate the changing of the tab content by fading pages in and out + final Resources res = getResources(); + final int duration = res.getInteger(R.integer.config_tabTransitionDuration); + + ObjectAnimator anim = ObjectAnimator.ofFloat(mAppsCustomizePane, "alpha", 0f); + anim.setDuration(duration); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(android.animation.Animator animation) { + mAppsCustomizePane.setContentType(type); + + ObjectAnimator anim = ObjectAnimator.ofFloat(mAppsCustomizePane, "alpha", 1f); + anim.setDuration(duration); + anim.start(); + } + }); + anim.start(); + } } /** diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java index b2a7603b5..c98e88575 100644 --- a/src/com/android/launcher2/CustomizePagedView.java +++ b/src/com/android/launcher2/CustomizePagedView.java @@ -249,7 +249,6 @@ public class CustomizePagedView extends PagedViewWithDraggableItems Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR); // Update the widgets/shortcuts to reflect changes in the set of available apps - mPageViewIconCache.retainAllApps(list); invalidatePageData(); } @@ -291,7 +290,6 @@ public class CustomizePagedView extends PagedViewWithDraggableItems int removeIndex = findAppByComponent(mApps, info); if (removeIndex > -1) { mApps.remove(removeIndex); - mPageViewIconCache.removeOutline(new PagedViewIconCache.Key(info)); } } } @@ -362,8 +360,6 @@ public class CustomizePagedView extends PagedViewWithDraggableItems ArrayList<ResolveInfo> retainShortcutList = new ArrayList<ResolveInfo>(mShortcutList); retainShortcutList.addAll(mWallpaperList); - mPageViewIconCache.retainAllShortcuts(retainShortcutList); - mPageViewIconCache.retainAllAppWidgets(mWidgetList); invalidatePageData(); } @@ -944,6 +940,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems } private void syncWidgetPages() { + /* if (mWidgetList == null) return; // we need to repopulate with the LinearLayout layout for the widget pages @@ -959,9 +956,11 @@ public class CustomizePagedView extends PagedViewWithDraggableItems LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); } + */ } private void syncWidgetPageItems(int page) { + /* // ensure that we have the right number of items on the pages LinearLayout layout = (LinearLayout) getChildAt(page); final ArrayList<AppWidgetProviderInfo> list = mWidgetPages.get(page); @@ -980,7 +979,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems R.layout.customize_paged_view_widget, layout, false); l.applyFromAppWidgetProviderInfo(info, icon, mMaxWidgetWidth, cellSpans, - mPageViewIconCache, createHolographicOutlines); + null, createHolographicOutlines); l.setTag(createItemInfo); l.setOnClickListener(this); l.setOnTouchListener(this); @@ -988,9 +987,11 @@ public class CustomizePagedView extends PagedViewWithDraggableItems layout.addView(l); } + */ } private void syncWallpaperPages() { + /* if (mWallpaperList == null) return; // We need to repopulate the LinearLayout for the wallpaper pages @@ -1007,9 +1008,11 @@ public class CustomizePagedView extends PagedViewWithDraggableItems LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); } + */ } private void syncWallpaperPageItems(int page) { + /* // Load the items on to the pages LinearLayout layout = (LinearLayout) getChildAt(page); layout.removeAllViews(); @@ -1026,15 +1029,17 @@ public class CustomizePagedView extends PagedViewWithDraggableItems PagedViewWidget l = (PagedViewWidget) mInflater.inflate( R.layout.customize_paged_view_wallpaper, layout, false); l.applyFromWallpaperInfo(info, mPackageManager, icon, mMaxWidgetWidth, - mPageViewIconCache, createHolographicOutlines); + null, createHolographicOutlines); l.setTag(info); l.setOnClickListener(this); layout.addView(l); } + */ } private void syncListPages(List<ResolveInfo> list) { + /* // we need to repopulate with PagedViewCellLayouts removeAllViews(); @@ -1045,9 +1050,11 @@ public class CustomizePagedView extends PagedViewWithDraggableItems setupPage(layout); addView(layout); } + */ } private void syncListPageItems(int page, List<ResolveInfo> list) { + /* // ensure that we have the right number of items on the pages final int numPages = getPageCount(); final int numCells = mCellCountX * mCellCountY; @@ -1063,7 +1070,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems PagedViewIcon icon = (PagedViewIcon) mInflater.inflate( R.layout.customize_paged_view_item, layout, false); - icon.applyFromResolveInfo(info, mPackageManager, mPageViewIconCache, + icon.applyFromResolveInfo(info, mPackageManager, null, ((LauncherApplication) mLauncher.getApplication()).getIconCache(), createHolographicOutlines); switch (mCustomizationType) { @@ -1089,9 +1096,11 @@ public class CustomizePagedView extends PagedViewWithDraggableItems setupPage(layout); layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1)); } + */ } private void syncAppPages() { + /* if (mApps == null) return; // We need to repopulate with PagedViewCellLayouts @@ -1104,9 +1113,11 @@ public class CustomizePagedView extends PagedViewWithDraggableItems setupPage(layout); addView(layout); } + */ } private void syncAppPageItems(int page) { + /* if (mApps == null) return; // ensure that we have the right number of items on the pages @@ -1123,7 +1134,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems PagedViewIcon icon = (PagedViewIcon) mInflater.inflate( R.layout.all_apps_paged_view_application, layout, false); icon.applyFromApplicationInfo( - info, mPageViewIconCache, true, createHolographicOutlines); + info, null, true, createHolographicOutlines); icon.setOnClickListener(this); icon.setOnTouchListener(this); icon.setOnLongClickListener(this); @@ -1134,6 +1145,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems setupPage(layout); layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1)); } + */ } @Override @@ -1148,6 +1160,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems @Override public void syncPages() { + /* boolean enforceMinimumPagedWidths = false; boolean centerPagedViewCellLayouts = false; switch (mCustomizationType) { @@ -1203,10 +1216,12 @@ public class CustomizePagedView extends PagedViewWithDraggableItems forceUpdateAdjacentPagesAlpha(); } }); + */ } @Override public void syncPageItems(int page) { + /* switch (mCustomizationType) { case WidgetCustomization: syncWidgetPageItems(page); @@ -1221,6 +1236,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems syncAppPageItems(page); break; } + */ } int getPageContentWidth() { diff --git a/src/com/android/launcher2/HolographicOutlineHelper.java b/src/com/android/launcher2/HolographicOutlineHelper.java index 80548fb5c..d2e1e7eb9 100644 --- a/src/com/android/launcher2/HolographicOutlineHelper.java +++ b/src/com/android/launcher2/HolographicOutlineHelper.java @@ -81,15 +81,15 @@ public class HolographicOutlineHelper { * Returns the interpolated holographic highlight alpha for the effect we want when scrolling * pages. */ - public float highlightAlphaInterpolator(float r) { - float maxAlpha = 0.8f; + public static float highlightAlphaInterpolator(float r) { + float maxAlpha = 0.6f; return (float) Math.pow(maxAlpha * (1.0f - r), 1.5f); } /** * Returns the interpolated view alpha for the effect we want when scrolling pages. */ - public float viewAlphaInterpolator(float r) { + public static float viewAlphaInterpolator(float r) { final float pivot = 0.95f; if (r < pivot) { return (float) Math.pow(r / pivot, 1.5f); diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java index ca0847ef9..9991d9d23 100644 --- a/src/com/android/launcher2/PagedView.java +++ b/src/com/android/launcher2/PagedView.java @@ -139,11 +139,6 @@ public abstract class PagedView extends ViewGroup { protected int mChoiceMode; private ActionMode mActionMode; - // NOTE: This is a shared icon cache across all the PagedViews. Currently it is only used in - // AllApps and Customize, and allows them to share holographic icons for the application view - // (which is in both). - protected static PagedViewIconCache mPageViewIconCache = new PagedViewIconCache(); - // If true, syncPages and syncPageItems will be called to refresh pages protected boolean mContentIsRefreshable = true; @@ -170,6 +165,9 @@ public abstract class PagedView extends ViewGroup { private static final int sScrollIndicatorFastFadeOutDuration = 50; private static final int sScrollIndicatorFadeOutDuration = 650; + // If set, will defer loading associated pages until the scrolling settles + private boolean mDeferLoadAssociatedPagesAfterScroll; + public interface PageSwitchListener { void onPageSwitch(View newPage, int newPageIndex); } @@ -375,6 +373,13 @@ public abstract class PagedView extends ViewGroup { mCurrentPage = Math.max(0, Math.min(mNextPage, getPageCount() - 1)); mNextPage = INVALID_PAGE; notifyPageSwitchListener(); + + // Load the associated pages if necessary + if (mDeferLoadAssociatedPagesAfterScroll) { + loadAssociatedPages(mCurrentPage); + mDeferLoadAssociatedPagesAfterScroll = false; + } + // We don't want to trigger a page end moving unless the page has settled // and the user has stopped scrolling if (mTouchState == TOUCH_STATE_REST) { @@ -1380,8 +1385,13 @@ public abstract class PagedView extends ViewGroup { if (!mScroller.isFinished()) mScroller.abortAnimation(); mScroller.startScroll(mUnboundedScrollX, 0, delta, 0, duration); - // only load some associated pages - loadAssociatedPages(mNextPage); + // Load associated pages immediately if someone else is handling the scroll, otherwise defer + // loading associated pages until the scroll settles + if (mDeferScrollUpdate) { + loadAssociatedPages(mNextPage); + } else { + mDeferLoadAssociatedPagesAfterScroll = true; + } notifyPageSwitchListener(); invalidate(); } diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java index d7f8784a5..9c37c019f 100644 --- a/src/com/android/launcher2/PagedViewCellLayout.java +++ b/src/com/android/launcher2/PagedViewCellLayout.java @@ -104,8 +104,8 @@ public class PagedViewCellLayout extends ViewGroup implements Page { @Override public void setAlpha(float alpha) { - mChildren.setAlpha(alpha); - mHolographicChildren.setAlpha(1.0f - alpha); + mChildren.setAlpha(HolographicOutlineHelper.viewAlphaInterpolator(alpha)); + mHolographicChildren.setAlpha(HolographicOutlineHelper.highlightAlphaInterpolator(alpha)); } void destroyHardwareLayers() { @@ -138,15 +138,6 @@ public class PagedViewCellLayout extends ViewGroup implements Page { } } - /** Syncs the holographic icon views to the child icon views */ - public void reloadHolographicIcons(boolean createHolographicOutlines) { - if (createHolographicOutlines) { - mChildren.loadHolographicOutlines(); - } else { - mChildren.clearHolographicOutlines(); - } - } - public boolean addViewToCellLayout(View child, int index, int childId, PagedViewCellLayout.LayoutParams params) { final PagedViewCellLayout.LayoutParams lp = params; diff --git a/src/com/android/launcher2/PagedViewCellLayoutChildren.java b/src/com/android/launcher2/PagedViewCellLayoutChildren.java index 1afdd03cf..0907c6058 100644 --- a/src/com/android/launcher2/PagedViewCellLayoutChildren.java +++ b/src/com/android/launcher2/PagedViewCellLayoutChildren.java @@ -168,26 +168,4 @@ public class PagedViewCellLayoutChildren extends ViewGroup { } } } - - public void loadHolographicOutlines() { - int count = getChildCount(); - for (int i = 0; i < count; i++) { - View view = getChildAt(i); - if (view instanceof PagedViewIcon) { - PagedViewIcon icon = (PagedViewIcon) view; - icon.loadHolographicIcon(); - } - } - } - - public void clearHolographicOutlines() { - int count = getChildCount(); - for (int i = 0; i < count; i++) { - View view = getChildAt(i); - if (view instanceof PagedViewIcon) { - PagedViewIcon icon = (PagedViewIcon) view; - icon.clearHolographicIcon(); - } - } - } } diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java index 30f0b1db2..a48a4effb 100644 --- a/src/com/android/launcher2/PagedViewIcon.java +++ b/src/com/android/launcher2/PagedViewIcon.java @@ -45,14 +45,10 @@ public class PagedViewIcon extends CachedTextView implements Checkable { // holographic outline private final Paint mPaint = new Paint(); - private static HolographicOutlineHelper sHolographicOutlineHelper; private Bitmap mCheckedOutline; private Bitmap mHolographicOutline; private Bitmap mIcon; - private PagedViewIconCache.Key mIconCacheKey; - private PagedViewIconCache mIconCache; - private int mAlpha = 255; private int mHolographicAlpha; @@ -62,42 +58,8 @@ public class PagedViewIcon extends CachedTextView implements Checkable { private int mCheckedFadeInDuration; private int mCheckedFadeOutDuration; - // Highlight colors - private int mHoloBlurColor; - private int mHoloOutlineColor; - HolographicPagedViewIcon mHolographicOutlineView; - - private static final HandlerThread sWorkerThread = new HandlerThread("pagedviewicon-helper"); - static { - sWorkerThread.start(); - } - - private static final int MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE = 1; - - private static final Handler sWorker = new Handler(sWorkerThread.getLooper()) { - private DeferredHandler mHandler = new DeferredHandler(); - private Paint mPaint = new Paint(); - public void handleMessage(Message msg) { - final PagedViewIcon icon = (PagedViewIcon) msg.obj; - - final Bitmap holographicOutline = Bitmap.createBitmap( - icon.mIcon.getWidth(), icon.mIcon.getHeight(), Bitmap.Config.ARGB_8888); - Canvas holographicOutlineCanvas = new Canvas(holographicOutline); - holographicOutlineCanvas.drawBitmap(icon.mIcon, 0, 0, mPaint); - - sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(holographicOutline, - holographicOutlineCanvas, icon.mHoloBlurColor, icon.mHoloOutlineColor); - - mHandler.post(new Runnable() { - public void run() { - icon.mHolographicOutline = holographicOutline; - icon.mIconCache.addOutline(icon.mIconCacheKey, holographicOutline); - icon.getHolographicOutlineView().invalidate(); - } - }); - } - }; + private HolographicOutlineHelper mHolographicOutlineHelper; public PagedViewIcon(Context context) { this(context, null); @@ -110,15 +72,6 @@ public class PagedViewIcon extends CachedTextView implements Checkable { public PagedViewIcon(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewIcon, defStyle, 0); - mHoloBlurColor = a.getColor(R.styleable.PagedViewIcon_blurColor, 0); - mHoloOutlineColor = a.getColor(R.styleable.PagedViewIcon_outlineColor, 0); - a.recycle(); - - if (sHolographicOutlineHelper == null) { - sHolographicOutlineHelper = new HolographicOutlineHelper(); - } - // Set up fade in/out constants final Resources r = context.getResources(); final int alpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha); @@ -141,69 +94,34 @@ public class PagedViewIcon extends CachedTextView implements Checkable { return mHolographicOutline; } - private boolean queueHolographicOutlineCreation() { - // Generate the outline in the background - if (mHolographicOutline == null) { - Message m = sWorker.obtainMessage(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE); - m.obj = this; - sWorker.sendMessage(m); - return true; - } - return false; - } - - public void loadHolographicIcon() { - if (mHolographicOutline == null) { - mHolographicOutline = mIconCache.getOutline(mIconCacheKey); - if (!queueHolographicOutlineCreation()) { - getHolographicOutlineView().invalidate(); - } - } - } - public void clearHolographicIcon() { - mHolographicOutline = null; - getHolographicOutlineView().invalidate(); - } - - public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache, - boolean scaleUp, boolean createHolographicOutlines) { - mIconCache = cache; - mIconCacheKey = new PagedViewIconCache.Key(info); + public void applyFromApplicationInfo(ApplicationInfo info, boolean scaleUp, + HolographicOutlineHelper holoOutlineHelper) { + mHolographicOutlineHelper = holoOutlineHelper; mIcon = info.iconBitmap; setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null); setText(info.title); setTag(info); - - if (createHolographicOutlines) { - mHolographicOutline = mIconCache.getOutline(mIconCacheKey); - if (!queueHolographicOutlineCreation()) { - getHolographicOutlineView().invalidate(); - } - } } public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager, - PagedViewIconCache cache, IconCache modelIconCache, boolean createHolographicOutlines) { + IconCache modelIconCache, HolographicOutlineHelper holoOutlineHelper) { + mHolographicOutlineHelper = holoOutlineHelper; ComponentName cn = new ComponentName(info.activityInfo.packageName, info.activityInfo.name); mIcon = modelIconCache.getIcon(cn, info); setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null); setText(info.loadLabel(packageManager)); setTag(info); + } - if (createHolographicOutlines) { - mIconCache = cache; - mIconCacheKey = new PagedViewIconCache.Key(info); - mHolographicOutline = mIconCache.getOutline(mIconCacheKey); - if (!queueHolographicOutlineCreation()) { - getHolographicOutlineView().invalidate(); - } - } + public void setHolographicOutline(Bitmap holoOutline) { + mHolographicOutline = holoOutline; + getHolographicOutlineView().invalidate(); } @Override public void setAlpha(float alpha) { - final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha); - final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha); + final float viewAlpha = mHolographicOutlineHelper.viewAlphaInterpolator(alpha); + final float holographicAlpha = mHolographicOutlineHelper.highlightAlphaInterpolator(alpha); int newViewAlpha = (int) (viewAlpha * 255); int newHolographicAlpha = (int) (holographicAlpha * 255); if ((mAlpha != newViewAlpha) || (mHolographicAlpha != newHolographicAlpha)) { @@ -247,12 +165,6 @@ public class PagedViewIcon extends CachedTextView implements Checkable { } @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this); - } - - @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return FocusHelper.handlePagedViewIconKeyEvent(this, keyCode, event) || super.onKeyDown(keyCode, event); diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java index 4061f1995..433a7858f 100644 --- a/src/com/android/launcher2/PagedViewWidget.java +++ b/src/com/android/launcher2/PagedViewWidget.java @@ -53,80 +53,22 @@ public class PagedViewWidget extends LinearLayout implements Checkable { static final String TAG = "PagedViewWidgetLayout"; private final Paint mPaint = new Paint(); - private static HolographicOutlineHelper sHolographicOutlineHelper; private Bitmap mHolographicOutline; - private final Canvas mHolographicOutlineCanvas = new Canvas(); - private FastBitmapDrawable mPreview; + private HolographicOutlineHelper mHolographicOutlineHelper; private ImageView mPreviewImageView; private final RectF mTmpScaleRect = new RectF(); - private final Rect mEraseStrokeRect = new Rect(); - private final Paint mEraseStrokeRectPaint = new Paint(); - private PagedViewIconCache.Key mIconCacheKey; - private PagedViewIconCache mIconCache; private String mDimensionsFormatString; private int mAlpha = 255; private int mHolographicAlpha; - // Highlight colors - private int mHoloBlurColor; - private int mHoloOutlineColor; - private boolean mIsChecked; private ObjectAnimator mCheckedAlphaAnimator; private float mCheckedAlpha = 1.0f; private int mCheckedFadeInDuration; private int mCheckedFadeOutDuration; - private static final HandlerThread sWorkerThread = new HandlerThread("pagedviewwidget-helper"); - static { - sWorkerThread.start(); - } - - private static final int MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE = 1; - - private static final Handler sWorker = new Handler(sWorkerThread.getLooper()) { - private DeferredHandler mHandler = new DeferredHandler(); - public void handleMessage(Message msg) { - final PagedViewWidget widget = (PagedViewWidget) msg.obj; - final int prevAlpha = widget.mPreview.getAlpha(); - final int width = Math.max(widget.mPreview.getIntrinsicWidth(), - widget.getMeasuredWidth()); - final int height = Math.max(widget.mPreview.getIntrinsicHeight(), - widget.getMeasuredHeight()); - final Bitmap outline = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - - widget.mHolographicOutlineCanvas.setBitmap(outline); - widget.mHolographicOutlineCanvas.save(); - widget.mHolographicOutlineCanvas.translate(widget.mPaddingLeft, widget.mPaddingTop); - widget.mPreview.setAlpha(255); - widget.mPreview.draw(widget.mHolographicOutlineCanvas); - widget.mPreview.setAlpha(prevAlpha); - // Temporary workaround to make the default widget outlines visible - widget.mHolographicOutlineCanvas.drawColor(Color.argb(156, 0, 0, 0), Mode.SRC_OVER); - widget.mHolographicOutlineCanvas.restore(); - - // To account for the fact that some previews run up straight to the edge (we subtract - // the edge from the holographic preview (before we apply the holograph) - widget.mEraseStrokeRect.set(0, 0, width, height); - widget.mHolographicOutlineCanvas.drawRect(widget.mEraseStrokeRect, - widget.mEraseStrokeRectPaint); - - sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(outline, - widget.mHolographicOutlineCanvas, widget.mHoloBlurColor, - widget.mHoloOutlineColor); - - mHandler.post(new Runnable() { - public void run() { - widget.mHolographicOutline = outline; - widget.mIconCache.addOutline(widget.mIconCacheKey, outline); - widget.invalidate(); - } - }); - } - }; - public PagedViewWidget(Context context) { this(context, null); } @@ -138,21 +80,6 @@ public class PagedViewWidget extends LinearLayout implements Checkable { public PagedViewWidget(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewWidget, - defStyle, 0); - mHoloBlurColor = a.getColor(R.styleable.PagedViewWidget_blurColor, 0); - mHoloOutlineColor = a.getColor(R.styleable.PagedViewWidget_outlineColor, 0); - mEraseStrokeRectPaint.setStyle(Paint.Style.STROKE); - mEraseStrokeRectPaint.setStrokeWidth(HolographicOutlineHelper.MIN_OUTER_BLUR_RADIUS); - mEraseStrokeRectPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); - mEraseStrokeRectPaint.setFilterBitmap(true); - mEraseStrokeRectPaint.setAntiAlias(true); - a.recycle(); - - if (sHolographicOutlineHelper == null) { - sHolographicOutlineHelper = new HolographicOutlineHelper(); - } - // Set up fade in/out constants final Resources r = context.getResources(); final int alpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha); @@ -169,18 +96,10 @@ public class PagedViewWidget extends LinearLayout implements Checkable { setClipToPadding(false); } - private void queueHolographicOutlineCreation() { - // Generate the outline in the background - if (mHolographicOutline == null && mPreview != null) { - Message m = sWorker.obtainMessage(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE); - m.obj = this; - sWorker.sendMessage(m); - } - } - public void applyFromAppWidgetProviderInfo(AppWidgetProviderInfo info, FastBitmapDrawable preview, int maxWidth, int[] cellSpan, - PagedViewIconCache cache, boolean createHolographicOutline) { + HolographicOutlineHelper holoOutlineHelper) { + mHolographicOutlineHelper = holoOutlineHelper; final ImageView image = (ImageView) findViewById(R.id.widget_preview); if (maxWidth > -1) { image.setMaxWidth(maxWidth); @@ -198,17 +117,11 @@ public class PagedViewWidget extends LinearLayout implements Checkable { if (!LauncherApplication.isScreenLarge()) { findViewById(R.id.divider).setVisibility(View.GONE); } - - if (createHolographicOutline) { - mIconCache = cache; - mIconCacheKey = new PagedViewIconCache.Key(info); - mHolographicOutline = mIconCache.getOutline(mIconCacheKey); - mPreview = preview; - } } public void applyFromResolveInfo(PackageManager pm, ResolveInfo info, - FastBitmapDrawable preview, PagedViewIconCache cache, boolean createHolographicOutline){ + FastBitmapDrawable preview, HolographicOutlineHelper holoOutlineHelper) { + mHolographicOutlineHelper = holoOutlineHelper; final ImageView image = (ImageView) findViewById(R.id.widget_preview); image.setImageDrawable(preview); mPreviewImageView = image; @@ -225,18 +138,11 @@ public class PagedViewWidget extends LinearLayout implements Checkable { if (!LauncherApplication.isScreenLarge()) { findViewById(R.id.divider).setVisibility(View.GONE); } - - if (createHolographicOutline) { - mIconCache = cache; - mIconCacheKey = new PagedViewIconCache.Key(info); - mHolographicOutline = mIconCache.getOutline(mIconCacheKey); - mPreview = preview; - } } public void applyFromWallpaperInfo(ResolveInfo info, PackageManager packageManager, - FastBitmapDrawable preview, int maxWidth, PagedViewIconCache cache, - boolean createHolographicOutline) { + FastBitmapDrawable preview, int maxWidth, HolographicOutlineHelper holoOutlineHelper) { + mHolographicOutlineHelper = holoOutlineHelper; ImageView image = (ImageView) findViewById(R.id.wallpaper_preview); image.setMaxWidth(maxWidth); image.setImageDrawable(preview); @@ -249,13 +155,11 @@ public class PagedViewWidget extends LinearLayout implements Checkable { if (!LauncherApplication.isScreenLarge()) { findViewById(R.id.divider).setVisibility(View.GONE); } + } - if (createHolographicOutline) { - mIconCache = cache; - mIconCacheKey = new PagedViewIconCache.Key(info); - mHolographicOutline = mIconCache.getOutline(mIconCacheKey); - mPreview = preview; - } + public void setHolographicOutline(Bitmap holoOutline) { + mHolographicOutline = holoOutline; + invalidate(); } @Override @@ -307,10 +211,16 @@ public class PagedViewWidget extends LinearLayout implements Checkable { return true; } + private void setChildrenAlpha(float alpha) { + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + getChildAt(i).setAlpha(alpha); + } + } @Override public void setAlpha(float alpha) { - final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha); - final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha); + final float viewAlpha = mHolographicOutlineHelper.viewAlphaInterpolator(alpha); + final float holographicAlpha = mHolographicOutlineHelper.highlightAlphaInterpolator(alpha); int newViewAlpha = (int) (viewAlpha * 255); int newHolographicAlpha = (int) (holographicAlpha * 255); if ((mAlpha != newViewAlpha) || (mHolographicAlpha != newHolographicAlpha)) { @@ -321,28 +231,6 @@ public class PagedViewWidget extends LinearLayout implements Checkable { } } - private void setChildrenAlpha(float alpha) { - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - getChildAt(i).setAlpha(alpha); - } - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - if (w > 0 && h > 0) { - queueHolographicOutlineCreation(); - } - - super.onSizeChanged(w, h, oldw, oldh); - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this); - } - void setChecked(boolean checked, boolean animate) { if (mIsChecked != checked) { mIsChecked = checked; |