From f314b0eab03bb354c14b6c89f694a6685bd246d9 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 16 Aug 2011 11:54:27 -0700 Subject: Improving transition between Apps/Widgets panes (5145408) Change-Id: Id4f73a89b646bbf168ee49e8bdeb34b85a52d9d4 --- res/layout/apps_customize_pane.xml | 5 ++ res/values/config.xml | 2 +- .../android/launcher2/AppsCustomizePagedView.java | 95 ++++++++++++++-------- .../android/launcher2/AppsCustomizeTabHost.java | 56 +++++++++---- src/com/android/launcher2/Launcher.java | 2 + src/com/android/launcher2/PagedView.java | 19 +++-- src/com/android/launcher2/Workspace.java | 2 +- 7 files changed, 126 insertions(+), 55 deletions(-) diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml index 05e7fc124..95b7dc2ef 100644 --- a/res/layout/apps_customize_pane.xml +++ b/res/layout/apps_customize_pane.xml @@ -63,6 +63,11 @@ launcher:widgetCountX="@integer/apps_customize_widget_cell_count_x" launcher:widgetCountY="@integer/apps_customize_widget_cell_count_y" launcher:maxGap="@dimen/workspace_max_gap" /> + 1000 - 100 + 200 diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java index 9d0399544..1da6fe07b 100644 --- a/src/com/android/launcher2/AppsCustomizePagedView.java +++ b/src/com/android/launcher2/AppsCustomizePagedView.java @@ -188,6 +188,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // Previews & outlines ArrayList mRunningTasks; private HolographicOutlineHelper mHolographicOutlineHelper; + private static final int sPageSleepDelay = 200; public AppsCustomizePagedView(Context context, AttributeSet attrs) { super(context, attrs); @@ -489,7 +490,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen public void setContentType(ContentType type) { mContentType = type; - invalidatePageData(0); + invalidatePageData(0, true); } public boolean isContentType(ContentType type) { @@ -536,7 +537,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen addView(layout); } } - public void syncAppsPageItems(int page) { + public void syncAppsPageItems(int page, boolean immediate) { // ensure that we have the right number of items on the pages int numPages = getPageCount(); int numCells = mCellCountX * mCellCountY; @@ -592,6 +593,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen return Process.THREAD_PRIORITY_DEFAULT; } } + private int getSleepForPage(int page) { + int pageDiff = Math.abs(page - mCurrentPage) - 1; + return Math.max(0, pageDiff * sPageSleepDelay); + } /** * Creates and executes a new AsyncTask to load a page of widget previews. */ @@ -612,37 +617,16 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen } } + // We introduce a slight delay to order the loading of side pages so that we don't thrash + final int sleepMs = getSleepForPage(page); AsyncTaskPageData pageData = new AsyncTaskPageData(page, widgets, cellWidth, cellHeight, cellCountX, 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 items = data.items; - ArrayList images = data.generatedImages; - 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(getWidgetPreview(info, cellSpans[0],cellSpans[1], - cellWidth, cellHeight)); - } else if (rawInfo instanceof ResolveInfo) { - // Fill in the shortcuts information - ResolveInfo info = (ResolveInfo) rawInfo; - images.add(getShortcutPreview(info, cellWidth, cellHeight)); - } - } + try { + Thread.sleep(sleepMs); + } catch (Exception e) {} + loadWidgetPreviewsInBackground(task, data); } }, new AsyncTaskCallback() { @@ -863,7 +847,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen addView(layout); } } - public void syncWidgetPageItems(int page) { + public void syncWidgetPageItems(int page, boolean immediate) { int numItemsPerPage = mWidgetCountX * mWidgetCountY; int contentWidth = mWidgetSpacingLayout.getContentWidth(); int contentHeight = mWidgetSpacingLayout.getContentHeight(); @@ -880,7 +864,50 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen items.add(mWidgets.get(i)); } - prepareLoadWidgetPreviewsTask(page, items, cellWidth, cellHeight, mWidgetCountX); + if (immediate) { + AsyncTaskPageData data = new AsyncTaskPageData(page, items, cellWidth, cellHeight, + mWidgetCountX, null, null); + loadWidgetPreviewsInBackground(null, data); + onSyncWidgetPageItems(data); + } else { + prepareLoadWidgetPreviewsTask(page, items, cellWidth, cellHeight, mWidgetCountX); + } + } + private void loadWidgetPreviewsInBackground(AppsCustomizeAsyncTask task, + AsyncTaskPageData data) { + if (task != null) { + // Ensure that this task starts running at the correct priority + task.syncThreadPriority(); + } + + // Load each of the widget/shortcut previews + ArrayList items = data.items; + ArrayList images = data.generatedImages; + int count = items.size(); + int cellWidth = data.cellWidth; + int cellHeight = data.cellHeight; + for (int i = 0; i < count; ++i) { + if (task != null) { + // Ensure we haven't been cancelled yet + if (task.isCancelled()) break; + // 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(getWidgetPreview(info, cellSpans[0],cellSpans[1], + cellWidth, cellHeight)); + } else if (rawInfo instanceof ResolveInfo) { + // Fill in the shortcuts information + ResolveInfo info = (ResolveInfo) rawInfo; + images.add(getShortcutPreview(info, cellWidth, cellHeight)); + } + } } private void onSyncWidgetPageItems(AsyncTaskPageData data) { int page = data.page; @@ -991,13 +1018,13 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen } } @Override - public void syncPageItems(int page) { + public void syncPageItems(int page, boolean immediate) { switch (mContentType) { case Applications: - syncAppsPageItems(page); + syncAppsPageItems(page, immediate); break; case Widgets: - syncWidgetPageItems(page); + syncWidgetPageItems(page, immediate); break; } } diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java index 6bd4c0355..d6ae1459e 100644 --- a/src/com/android/launcher2/AppsCustomizeTabHost.java +++ b/src/com/android/launcher2/AppsCustomizeTabHost.java @@ -18,15 +18,19 @@ package com.android.launcher2; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Canvas; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.view.ViewPropertyAnimator; +import android.view.animation.DecelerateInterpolator; +import android.widget.ImageView; import android.widget.TabHost; import android.widget.TabWidget; import android.widget.TextView; @@ -44,6 +48,7 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona private ViewGroup mTabs; private ViewGroup mTabsContainer; private AppsCustomizePagedView mAppsCustomizePane; + private ImageView mAnimationBuffer; private boolean mInTransition; private boolean mResetAfterTransition; @@ -89,6 +94,7 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona mTabs = tabs; mTabsContainer = tabsContainer; mAppsCustomizePane = appsCustomizePane; + mAnimationBuffer = (ImageView) findViewById(R.id.animation_buffer); if (tabs == null || mAppsCustomizePane == null) throw new Resources.NotFoundException(); // Configure the tabs content factory to return the same paged view (that we change the @@ -168,31 +174,53 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona 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() { + // We post a runnable here because there is a delay while the first page is loading and + // the feedback from having changed the tab almost feels better than having it stick + post(new Runnable() { @Override - public void onAnimationStart(android.animation.Animator animation) { + public void run() { + // Setup the animation buffer + Bitmap b = Bitmap.createBitmap(mAppsCustomizePane.getMeasuredWidth(), + mAppsCustomizePane.getMeasuredHeight(), Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(b); + mAppsCustomizePane.draw(c); + mAppsCustomizePane.setAlpha(0f); + mAnimationBuffer.setImageBitmap(b); + mAnimationBuffer.setAlpha(1f); + mAnimationBuffer.setVisibility(View.VISIBLE); + c.setBitmap(null); + b = null; + + // Toggle the new content onTabChangedStart(); - } - @Override - public void onAnimationEnd(android.animation.Animator animation) { onTabChangedEnd(type); - ObjectAnimator anim = ObjectAnimator.ofFloat(mAppsCustomizePane, "alpha", 1f); - anim.setDuration(duration); - anim.addListener(new AnimatorListenerAdapter() { + // Animate the transition + ObjectAnimator outAnim = ObjectAnimator.ofFloat(mAnimationBuffer, "alpha", 0f); + outAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mAnimationBuffer.setVisibility(View.GONE); + mAnimationBuffer.setImageBitmap(null); + } + }); + ObjectAnimator inAnim = ObjectAnimator.ofFloat(mAppsCustomizePane, "alpha", 1f); + inAnim.addListener(new AnimatorListenerAdapter() { @Override - public void onAnimationEnd(android.animation.Animator animation) { + public void onAnimationEnd(Animator animation) { if (!LauncherApplication.isScreenLarge()) { mAppsCustomizePane.flashScrollingIndicator(); } + mAppsCustomizePane.loadAssociatedPages( + mAppsCustomizePane.getCurrentPage()); } }); - anim.start(); + AnimatorSet animSet = new AnimatorSet(); + animSet.playTogether(outAnim, inAnim); + animSet.setDuration(duration); + animSet.start(); } }); - anim.start(); } } diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 7ab41bc4e..ad0c42b24 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -670,6 +670,8 @@ public final class Launcher extends Activity mAppsCustomizeContent.setContentType( mAppsCustomizeTabHost.getContentTypeForTabTag(curTab)); mAppsCustomizeTabHost.setCurrentTabByTag(curTab); + mAppsCustomizeContent.loadAssociatedPages( + mAppsCustomizeContent.getCurrentPage()); } // Note: currently we do not restore the page for the AppsCustomize pane because the diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java index d2d734cf3..6e2636354 100644 --- a/src/com/android/launcher2/PagedView.java +++ b/src/com/android/launcher2/PagedView.java @@ -1494,7 +1494,10 @@ public abstract class PagedView extends ViewGroup { }; } - public void loadAssociatedPages(int page) { + protected void loadAssociatedPages(int page) { + loadAssociatedPages(page, false); + } + protected void loadAssociatedPages(int page, boolean immediateAndOnly) { if (mContentIsRefreshable) { final int count = getChildCount(); if (page < count) { @@ -1503,11 +1506,14 @@ public abstract class PagedView extends ViewGroup { if (DEBUG) Log.d(TAG, "loadAssociatedPages: " + lowerPageBound + "/" + upperPageBound); for (int i = 0; i < count; ++i) { + if ((i != page) && immediateAndOnly) { + continue; + } Page layout = (Page) getChildAt(i); final int childCount = layout.getPageChildCount(); if (lowerPageBound <= i && i <= upperPageBound) { if (mDirtyPageContent.get(i)) { - syncPageItems(i); + syncPageItems(i, (i == page) && immediateAndOnly); mDirtyPageContent.set(i, false); } } else { @@ -1607,7 +1613,7 @@ public abstract class PagedView extends ViewGroup { * This method is called to synchronize the items that are on a particular page. If views on * the page can be reused, then they should be updated within this method. */ - public abstract void syncPageItems(int page); + public abstract void syncPageItems(int page, boolean immediate); protected void postInvalidatePageData(final boolean clearViews) { post(new Runnable() { @@ -1622,9 +1628,12 @@ public abstract class PagedView extends ViewGroup { } protected void invalidatePageData() { - invalidatePageData(-1); + invalidatePageData(-1, false); } protected void invalidatePageData(int currentPage) { + invalidatePageData(currentPage, false); + } + protected void invalidatePageData(int currentPage, boolean immediateAndOnly) { if (!mIsDataReady) { return; } @@ -1651,7 +1660,7 @@ public abstract class PagedView extends ViewGroup { } // Load any pages that are necessary for the current window of views - loadAssociatedPages(mCurrentPage); + loadAssociatedPages(mCurrentPage, immediateAndOnly); mDirtyPageAlpha = true; updateAdjacentPagesAlpha(); requestLayout(); diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 947c94624..c04762fa3 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -3544,7 +3544,7 @@ public class Workspace extends SmoothPagedView } @Override - public void syncPageItems(int page) { + public void syncPageItems(int page, boolean immediate) { } @Override -- cgit v1.2.3