diff options
author | Nebojsa Cvetkovic <nebkat@gmail.com> | 2014-01-05 23:15:48 +0000 |
---|---|---|
committer | Danesh M <daneshm90@gmail.com> | 2014-01-24 16:25:19 -0800 |
commit | 78ffd65b78ce1e7c97fb408091d401aa6dd3193c (patch) | |
tree | 743145b03dffc3280bd3db7eaed80574cd49c301 | |
parent | 233a1403274298f510bb57f02ffde54e40d3ec0b (diff) | |
download | android_packages_apps_Trebuchet-78ffd65b78ce1e7c97fb408091d401aa6dd3193c.tar.gz android_packages_apps_Trebuchet-78ffd65b78ce1e7c97fb408091d401aa6dd3193c.tar.bz2 android_packages_apps_Trebuchet-78ffd65b78ce1e7c97fb408091d401aa6dd3193c.zip |
PagedView: Transition Effects
Change-Id: Ib134705952877165c334181548d577b3dceece68
-rw-r--r-- | res/layout/overview_panel.xml | 61 | ||||
-rw-r--r-- | res/values/cm_arrays.xml | 33 | ||||
-rw-r--r-- | res/values/cm_strings.xml | 2 | ||||
-rw-r--r-- | res/values/dimens.xml | 2 | ||||
-rw-r--r-- | res/values/preferences_defaults.xml | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/AppsCustomizePagedView.java | 201 | ||||
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 111 | ||||
-rw-r--r-- | src/com/android/launcher3/PagedView.java | 419 | ||||
-rw-r--r-- | src/com/android/launcher3/Workspace.java | 77 | ||||
-rw-r--r-- | src/com/android/launcher3/settings/SettingsProvider.java | 2 |
10 files changed, 699 insertions, 211 deletions
diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml index ada2b2483..fad5ebe18 100644 --- a/res/layout/overview_panel.xml +++ b/res/layout/overview_panel.xml @@ -17,19 +17,44 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> - <TextView - android:id="@+id/default_screen_button" + + <LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:orientation="horizontal" android:layout_gravity="center_horizontal|top" - android:paddingTop="@dimen/overview_panel_top_padding" - android:text="@string/default_screen_button_text" - android:drawablePadding="4dp" - android:drawableTop="@drawable/default_screen_button" - android:gravity="center_horizontal" - android:fontFamily="sans-serif-condensed" - android:textAllCaps="true" - android:textSize="12sp" /> + android:paddingTop="@dimen/overview_panel_top_padding"> + + <TextView + android:id="@+id/default_screen_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingLeft="@dimen/overview_panel_button_spacing" + android:paddingRight="@dimen/overview_panel_button_spacing" + android:text="@string/default_screen_button_text" + android:drawablePadding="4dp" + android:drawableTop="@drawable/default_screen_button" + android:gravity="center_horizontal" + android:fontFamily="sans-serif-condensed" + android:textAllCaps="true" + android:textSize="12sp" /> + + <TextView + android:id="@+id/transition_effect_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingLeft="@dimen/overview_panel_button_spacing" + android:paddingRight="@dimen/overview_panel_button_spacing" + android:text="@string/transition_effect_button_text" + android:drawablePadding="4dp" + android:drawableTop="@drawable/wallpaper_button" + android:gravity="center_horizontal" + android:fontFamily="sans-serif-condensed" + android:textAllCaps="true" + android:textSize="12sp" /> + + </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" @@ -43,6 +68,8 @@ android:id="@+id/wallpaper_button" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:paddingLeft="@dimen/overview_panel_button_spacing" + android:paddingRight="@dimen/overview_panel_button_spacing" android:text="@string/wallpaper_button_text" android:drawablePadding="4dp" android:drawableTop="@drawable/wallpaper_button" @@ -54,6 +81,8 @@ android:id="@+id/sort_button" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:paddingLeft="@dimen/overview_panel_button_spacing" + android:paddingRight="@dimen/overview_panel_button_spacing" android:text="@string/sort_button_text" android:drawablePadding="4dp" android:drawableTop="@drawable/wallpaper_button" @@ -61,13 +90,12 @@ android:fontFamily="sans-serif-condensed" android:textAllCaps="true" android:textSize="12sp" /> - <Space - android:layout_width="@dimen/overview_panel_buttonSpacing" - android:layout_height="wrap_content"/> <TextView android:id="@+id/widget_button" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:paddingLeft="@dimen/overview_panel_button_spacing" + android:paddingRight="@dimen/overview_panel_button_spacing" android:text="@string/widget_button_text" android:drawablePadding="4dp" android:gravity="center_horizontal" @@ -79,6 +107,8 @@ android:id="@+id/filter_button" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:paddingLeft="@dimen/overview_panel_button_spacing" + android:paddingRight="@dimen/overview_panel_button_spacing" android:text="@string/filter_button_text" android:drawablePadding="4dp" android:gravity="center_horizontal" @@ -86,13 +116,12 @@ android:fontFamily="sans-serif-condensed" android:textAllCaps="true" android:textSize="12sp"/> - <Space - android:layout_width="@dimen/overview_panel_buttonSpacing" - android:layout_height="wrap_content"/> <TextView android:id="@+id/settings_button" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:paddingLeft="@dimen/overview_panel_button_spacing" + android:paddingRight="@dimen/overview_panel_button_spacing" android:text="@string/settings_button_text" android:drawablePadding="4dp" android:gravity="center_horizontal" diff --git a/res/values/cm_arrays.xml b/res/values/cm_arrays.xml index 580e89317..5d614ab2d 100644 --- a/res/values/cm_arrays.xml +++ b/res/values/cm_arrays.xml @@ -10,4 +10,37 @@ <item>sans-serif-light</item> <item>sans-serif-condensed</item> </string-array> + + <string-array name="transition_effect_entries"> + <item>None</item> + <item>Zoom In</item> + <item>Zoom Out</item> + <item>Rotate Up</item> + <item>Rotate Down</item> + <item>Cube In</item> + <item>Cube Out</item> + <item>Stack</item> + <item>Accordion</item> + <item>Flip</item> + <item>Cylinder In</item> + <item>Cylinder Out</item> + <item>Carousel</item> + <item>Overview</item> + </string-array> + <string-array name="transition_effect_values"> + <item>none</item> + <item>zoom-in</item> + <item>zoom-out</item> + <item>rotate-up</item> + <item>rotate-down</item> + <item>cube-in</item> + <item>cube-out</item> + <item>stack</item> + <item>accordion</item> + <item>flip</item> + <item>cylinder-in</item> + <item>cylinder-out</item> + <item>carousel</item> + <item>overview</item> + </string-array> </resources>
\ No newline at end of file diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml index 2dc3fa4bc..50b8bad73 100644 --- a/res/values/cm_strings.xml +++ b/res/values/cm_strings.xml @@ -12,6 +12,8 @@ <string name="filter_button_text">Filter</string> <!-- Text for default screen button --> <string name="default_screen_button_text">Default Screen</string> + <!-- Text for transition effect button --> + <string name="transition_effect_button_text">Scroll Effect</string> <string name="sort_mode_title">Title</string> <string name="sort_mode_launch_count">Launch Count</string> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 8176c8192..3b692a1d1 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -43,7 +43,7 @@ <dimen name="workspace_spring_loaded_page_spacing">15dp</dimen> <dimen name="overview_panel_top_padding">20dp</dimen> <dimen name="overview_panel_bottom_padding">50dp</dimen> - <dimen name="overview_panel_buttonSpacing">60dp</dimen> + <dimen name="overview_panel_button_spacing">30dp</dimen> <dimen name="overview_mode_page_offset">130dp</dimen> <!-- QSB --> diff --git a/res/values/preferences_defaults.xml b/res/values/preferences_defaults.xml index 9fa44b27e..ebb1650f4 100644 --- a/res/values/preferences_defaults.xml +++ b/res/values/preferences_defaults.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <bool name="preferences_interface_homescreen_search_default">true</bool> + <string name="preferences_interface_homescreen_scrolling_transition_effect">none</string> <bool name="preferences_interface_homescreen_scrolling_wallpaper_scroll_default">true</bool> <bool name="preferences_interface_homescreen_scrolling_page_outlines_default">@bool/config_workspaceDefaultShowOutlines</bool> + <string name="preferences_interface_drawer_scrolling_transition_effect">stack</string> <bool name="preferences_interface_general_icons_large_default">@bool/config_largeIcons</bool> <string name="preferences_interface_general_icons_text_font_family_default">sans-serif-condensed</string> <integer name="preferences_interface_general_icons_text_font_style_default">0</integer> diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java index 34625dfd7..44f50b200 100644 --- a/src/com/android/launcher3/AppsCustomizePagedView.java +++ b/src/com/android/launcher3/AppsCustomizePagedView.java @@ -56,6 +56,7 @@ import android.widget.ImageView; import android.widget.Toast; import com.android.launcher3.DropTarget.DragObject; +import com.android.launcher3.settings.SettingsProvider; import java.util.ArrayList; import java.util.Collections; @@ -213,28 +214,15 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // Animation values private float mNewScale; private float[] mOldBackgroundAlphas; - private float[] mOldTranslationXs; - private float[] mOldTranslationYs; - private float[] mOldScaleXs; - private float[] mOldScaleYs; private float[] mOldAlphas; private float[] mNewBackgroundAlphas; - private float[] mNewTranslationXs; - private float[] mNewTranslationYs; - private float[] mNewScaleXs; - private float[] mNewScaleYs; private float[] mNewAlphas; // Relating to the scroll and overscroll effects - Workspace.ZInterpolator mZInterpolator = new Workspace.ZInterpolator(0.5f); - private static float CAMERA_DISTANCE = 6500; - private static float TRANSITION_SCALE_FACTOR = 0.74f; - private static float TRANSITION_PIVOT = 0.65f; private static float TRANSITION_MAX_ROTATION = 22; private static final float ALPHA_CUTOFF_THRESHOLD = 0.01f; - private static final boolean PERFORM_OVERSCROLL_ROTATION = true; - private AccelerateInterpolator mAlphaInterpolator = new AccelerateInterpolator(0.9f); - private DecelerateInterpolator mLeftScreenAlphaInterpolator = new DecelerateInterpolator(4); + private boolean mOverscrollTransformsSet; + private float mLastOverscrollPivotX; public static boolean DISABLE_ALL_APPS = false; @@ -311,6 +299,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // (top + bottom) mFadeInAdjacentScreens = false; + TransitionEffect.setFromString(this, SettingsProvider.getString(context, + SettingsProvider.SETTINGS_UI_DRAWER_SCROLLING_TRANSITION_EFFECT, + R.string.preferences_interface_drawer_scrolling_transition_effect)); + // Unless otherwise specified this view is important for accessibility. if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); @@ -324,6 +316,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen Context context = getContext(); Resources r = context.getResources(); + mCameraDistance = (int) CAMERA_DISTANCE;//r.getInteger(R.integer.config_cameraDistance); setDragSlopeThreshold(r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold)/100f); mOverviewModeShrinkFactor = r.getInteger(R.integer.config_workspaceOverviewShrinkPercentage) / 100.0f; @@ -1057,6 +1050,15 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen } @Override + public void setChildAlpha(View child, float alpha) { + if (child instanceof CellLayout) { + ((CellLayout) child).getShortcutsAndWidgets().setAlpha(alpha); + } else { + child.setAlpha(alpha); + } + } + + @Override public void onChildViewAdded(View parent, View child) { // For overview mode if (child instanceof CellLayout) { @@ -1068,6 +1070,12 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen super.onChildViewAdded(parent, child); } + protected boolean shouldDrawChild(View child) { + return super.shouldDrawChild(child) && (mIsSwitchingState || + !(child instanceof CellLayout) || + ((CellLayout) child).getShortcutsAndWidgets().getAlpha() > 0); + } + public void syncAppsPageItems(int page, boolean immediate) { // ensure that we have the right number of items on the pages final boolean isRtl = isLayoutRtl(); @@ -1433,92 +1441,51 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen @Override protected void screenScrolled(int screenCenter) { final boolean isRtl = isLayoutRtl(); - super.screenScrolled(screenCenter); + mUseTransitionEffect = !isInOverviewMode() && !mIsSwitchingState; + + super.screenScrolled(screenCenter); enableHwLayersOnVisiblePages(); - if (isInOverviewMode()) { - return; - } + boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX; - for (int i = 0; i < getChildCount(); i++) { - View v = getPageAt(i); - if (v != null) { - float scrollProgress = getScrollProgress(screenCenter, v, i); + if (isInOverscroll) { + int index = 0; + float pivotX = 0f; + final float leftBiasedPivot = 0.35f; + final float rightBiasedPivot = 0.65f; + final int lowerIndex = 0; + final int upperIndex = getChildCount() - 1; - float interpolatedProgress; - float translationX; - float maxScrollProgress = Math.max(0, scrollProgress); - float minScrollProgress = Math.min(0, scrollProgress); + final boolean isLeftPage = mOverScrollX < 0; + index = (!isRtl && isLeftPage) || (isRtl && !isLeftPage) ? lowerIndex : upperIndex; + pivotX = isLeftPage ? rightBiasedPivot : leftBiasedPivot; - if (isRtl) { - translationX = maxScrollProgress * v.getMeasuredWidth(); - interpolatedProgress = mZInterpolator.getInterpolation(Math.abs(maxScrollProgress)); - } else { - translationX = minScrollProgress * v.getMeasuredWidth(); - interpolatedProgress = mZInterpolator.getInterpolation(Math.abs(minScrollProgress)); - } - float scale = (1 - interpolatedProgress) + - interpolatedProgress * TRANSITION_SCALE_FACTOR; - - float alpha; - if (isRtl && (scrollProgress > 0)) { - alpha = mAlphaInterpolator.getInterpolation(1 - Math.abs(maxScrollProgress)); - } else if (!isRtl && (scrollProgress < 0)) { - alpha = mAlphaInterpolator.getInterpolation(1 - Math.abs(scrollProgress)); - } else { - // On large screens we need to fade the page as it nears its leftmost position - alpha = mLeftScreenAlphaInterpolator.getInterpolation(1 - scrollProgress); - } - - v.setCameraDistance(mDensity * CAMERA_DISTANCE); - int pageWidth = v.getMeasuredWidth(); - int pageHeight = v.getMeasuredHeight(); - - if (PERFORM_OVERSCROLL_ROTATION) { - float xPivot = isRtl ? 1f - TRANSITION_PIVOT : TRANSITION_PIVOT; - boolean isOverscrollingFirstPage = isRtl ? scrollProgress > 0 : scrollProgress < 0; - boolean isOverscrollingLastPage = isRtl ? scrollProgress < 0 : scrollProgress > 0; - - if (i == 0 && isOverscrollingFirstPage) { - // Overscroll to the left - v.setPivotX(xPivot * pageWidth); - v.setRotationY(-TRANSITION_MAX_ROTATION * scrollProgress); - scale = 1.0f; - alpha = 1.0f; - // On the first page, we don't want the page to have any lateral motion - translationX = 0; - } else if (i == getChildCount() - 1 && isOverscrollingLastPage) { - // Overscroll to the right - v.setPivotX((1 - xPivot) * pageWidth); - v.setRotationY(-TRANSITION_MAX_ROTATION * scrollProgress); - scale = 1.0f; - alpha = 1.0f; - // On the last page, we don't want the page to have any lateral motion. - translationX = 0; - } else { - v.setPivotY(pageHeight / 2.0f); - v.setPivotX(pageWidth / 2.0f); - v.setRotationY(0f); - } - } + View v = getPageAt(index); - v.setTranslationX(translationX); - v.setScaleX(scale); - v.setScaleY(scale); - if (v instanceof CellLayout) { - ((CellLayout) v).getShortcutsAndWidgets().setAlpha(alpha); - } else { - v.setAlpha(alpha); - } + if (!mOverscrollTransformsSet || Float.compare(mLastOverscrollPivotX, pivotX) != 0) { + mOverscrollTransformsSet = true; + mLastOverscrollPivotX = pivotX; + v.setCameraDistance(mDensity * mCameraDistance); + v.setPivotX(v.getMeasuredWidth() * pivotX); + } - // If the view has 0 alpha, we set it to be invisible so as to prevent - // it from accepting touches - if (alpha == 0) { - v.setVisibility(INVISIBLE); - } else if (v.getVisibility() != VISIBLE) { - v.setVisibility(VISIBLE); - } + float scrollProgress = getScrollProgress(screenCenter, v, index); + float rotation = -TRANSITION_MAX_ROTATION * scrollProgress; + v.setRotationY(rotation); + } else { + if (mOverscrollTransformsSet) { + mOverscrollTransformsSet = false; + View v0 = getPageAt(0); + View v1 = getPageAt(getChildCount() - 1); + v0.setRotationY(0); + v1.setRotationY(0); + v0.setCameraDistance(mDensity * mCameraDistance); + v1.setCameraDistance(mDensity * mCameraDistance); + v0.setPivotX(v0.getMeasuredWidth() / 2); + v1.setPivotX(v1.getMeasuredWidth() / 2); + v0.setPivotY(v0.getMeasuredHeight() / 2); + v1.setPivotY(v1.getMeasuredHeight() / 2); } } } @@ -1631,16 +1598,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen final int childCount = getChildCount(); if (mOldBackgroundAlphas != null) return; mOldBackgroundAlphas = new float[childCount]; - mOldTranslationXs = new float[childCount]; - mOldTranslationYs = new float[childCount]; - mOldScaleXs = new float[childCount]; - mOldScaleYs = new float[childCount]; mOldAlphas = new float[childCount]; mNewBackgroundAlphas = new float[childCount]; - mNewTranslationXs = new float[childCount]; - mNewTranslationYs = new float[childCount]; - mNewScaleXs = new float[childCount]; - mNewScaleYs = new float[childCount]; mNewAlphas = new float[childCount]; } @@ -1680,15 +1639,17 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen for (int i = 0; i < getChildCount(); i++) { final CellLayout cl = (CellLayout) getChildAt(i); - float translationX = 0f; - float translationY = 0f; - float scaleX = 1f; - float scaleY = 1f; float finalAlpha = 1f; if (stateIsOverview) { cl.setVisibility(VISIBLE); cl.setTranslationX(0f); + cl.setTranslationY(0f); + cl.setPivotX(cl.getMeasuredWidth() * 0.5f); + cl.setPivotY(cl.getMeasuredHeight() * 0.5f); + cl.setRotation(0f); + cl.setRotationY(0f); + cl.setRotationX(0f); cl.setScaleX(1f); cl.setScaleY(1f); cl.setShortcutAndWidgetAlpha(1f); @@ -1698,22 +1659,9 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen mNewAlphas[i] = finalAlpha; if (animated) { mOldBackgroundAlphas[i] = cl.getBackgroundAlpha(); - mOldTranslationXs[i] = cl.getTranslationX(); - mOldTranslationYs[i] = cl.getTranslationY(); - mOldScaleXs[i] = cl.getScaleX(); - mNewScaleXs[i] = cl.getScaleY(); - mNewBackgroundAlphas[i] = finalBackgroundAlpha; - mNewTranslationXs[i] = translationX; - mNewTranslationYs[i] = translationY; - mNewScaleXs[i] = scaleX; - mNewScaleYs[i] = scaleY; } else { cl.setBackgroundAlpha(finalBackgroundAlpha); - cl.setTranslationX(translationX); - cl.setTranslationY(translationY); - cl.setScaleX(scaleX); - cl.setScaleY(scaleY); cl.setShortcutAndWidgetAlpha(finalAlpha); } } @@ -1762,23 +1710,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen final CellLayout cl = (CellLayout) getChildAt(i); if (mOldAlphas[i] == 0 && mNewAlphas[i] == 0) { cl.setBackgroundAlpha(mNewBackgroundAlphas[i]); - cl.setTranslationX(mNewTranslationXs[i]); - cl.setTranslationY(mNewTranslationYs[i]); - cl.setScaleX(mNewScaleXs[i]); - cl.setScaleY(mNewScaleYs[i]); cl.getShortcutsAndWidgets().setAlpha(mNewAlphas[i]); } else { - LauncherViewPropertyAnimator a = new LauncherViewPropertyAnimator(cl); - a.translationX(mNewTranslationXs[i]) - .translationY(mNewTranslationYs[i]) - .scaleX(mNewScaleXs[i]) - .scaleY(mNewScaleYs[i]) - .setDuration(duration) - .setInterpolator(mZoomInInterpolator); - anim.play(a); - a = new LauncherViewPropertyAnimator(cl.getShortcutsAndWidgets()); - a.translationX(mNewTranslationXs[i]) - .alpha(mNewAlphas[i]) + LauncherViewPropertyAnimator a = new LauncherViewPropertyAnimator(cl.getShortcutsAndWidgets()); + a.alpha(mNewAlphas[i]) .setDuration(duration) .setInterpolator(mZoomInInterpolator); anim.play(a); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index bfd5271df..d0df9c371 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -29,6 +29,8 @@ import android.animation.ValueAnimator.AnimatorUpdateListener; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; +import android.app.AlertDialog; +import android.app.Dialog; import android.app.SearchManager; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; @@ -39,6 +41,7 @@ import android.content.ComponentCallbacks2; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; @@ -111,7 +114,6 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; -import java.lang.reflect.Array; import java.text.DateFormat; import java.util.ArrayList; import java.util.Collection; @@ -271,6 +273,8 @@ public class Launcher extends Activity private Bundle mSavedInstanceState; + private Dialog mTransitionEffectDialog; + private LauncherModel mModel; private IconCache mIconCache; private boolean mUserPresent = true; @@ -1029,6 +1033,88 @@ public class Launcher extends Activity popupMenu.show(); } + public void onClickTransitionEffectButton(View v) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.transition_effect_button_text); + + if (isAllAppsVisible()) { + mAppsCustomizeContent.exitOverviewMode(true); + } else { + mWorkspace.exitOverviewMode(true); + } + + final PagedView pagedView = isAllAppsVisible() ? mAppsCustomizeContent : mWorkspace; + final PagedView.TransitionEffect oldEffect = pagedView.getTransitionEffect(); + final String oldEffectName = oldEffect != null ? oldEffect.getName() : + PagedView.TransitionEffect.TRANSITION_EFFECT_NONE; + + final String[] entries = getResources().getStringArray(R.array.transition_effect_entries); + final String[] values = getResources().getStringArray(R.array.transition_effect_values); + + int selected = -1; + for (int i = values.length - 1; i >= 0; i--) { + if (values[i].equals(oldEffectName)) { + selected = i; + break; + } + } + + builder.setSingleChoiceItems(entries, selected, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String effect = values[which]; + PagedView.TransitionEffect.setFromString(pagedView, effect); + + final int currentPage = pagedView.getNextPage(); + final int nextPage = currentPage + (currentPage != pagedView.getPageCount() - 1 ? 1 : -1); + + + pagedView.snapToPageImmediately(currentPage); + pagedView.snapToPage(nextPage, new Runnable() { + @Override + public void run() { + pagedView.snapToPage(currentPage); + } + }); + } + }) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + PagedView.TransitionEffect effect = pagedView.getTransitionEffect(); + String name = effect != null ? effect.getName() : PagedView.TransitionEffect.TRANSITION_EFFECT_NONE; + + SettingsProvider.get(Launcher.this).edit() + .putString(!isAllAppsVisible() ? + SettingsProvider.SETTINGS_UI_HOMESCREEN_SCROLLING_TRANSITION_EFFECT : + SettingsProvider.SETTINGS_UI_DRAWER_SCROLLING_TRANSITION_EFFECT, name) + .commit(); + + dialog.dismiss(); + } + }) + .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + pagedView.setTransitionEffect(oldEffect); + } + }) + .setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + mTransitionEffectDialog = null; + } + }); + mTransitionEffectDialog = builder.create(); + mTransitionEffectDialog.show(); + mTransitionEffectDialog.setCanceledOnTouchOutside(true); + mTransitionEffectDialog.getWindow().getDecorView().setAlpha(0.6f); + } + public interface QSBScroller { public void setScrollY(int scrollY); } @@ -1239,11 +1325,20 @@ public class Launcher extends Activity }); defaultScreenButton.setOnTouchListener(getHapticFeedbackTouchListener()); + View transitionEffectButton = findViewById(R.id.transition_effect_button); + transitionEffectButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + onClickTransitionEffectButton(arg0); + } + }); + transitionEffectButton.setOnTouchListener(getHapticFeedbackTouchListener()); + View sortButton = findViewById(R.id.sort_button); sortButton.setOnClickListener(new OnClickListener() { @Override - public void onClick(View v) { - onClickSortModeButton(v); + public void onClick(View arg0) { + onClickSortModeButton(arg0); } }); sortButton.setOnTouchListener(getHapticFeedbackTouchListener()); @@ -1732,6 +1827,10 @@ public class Launcher extends Activity // also will cancel mWaitingForResult. closeSystemDialogs(); + if (mTransitionEffectDialog != null) { + mTransitionEffectDialog.cancel(); + } + final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); @@ -2761,12 +2860,16 @@ public class Launcher extends Activity public void updateOverviewPanel() { View defaultScreenButton = mOverviewPanel.findViewById(R.id.default_screen_button); + View transitionEffectButton = mOverviewPanel.findViewById(R.id.transition_effect_button); View widgetButton = mOverviewPanel.findViewById(R.id.widget_button); View wallpaperButton = mOverviewPanel.findViewById(R.id.wallpaper_button); View sortButton = mOverviewPanel.findViewById(R.id.sort_button); View filterButton = mOverviewPanel.findViewById(R.id.filter_button); - defaultScreenButton.setVisibility(!isAllAppsVisible() ? View.VISIBLE : View.GONE); + PagedView pagedView = !isAllAppsVisible() ? mWorkspace : mAppsCustomizeContent; + + defaultScreenButton.setVisibility((!isAllAppsVisible() && pagedView.getPageCount() > 1) ? View.VISIBLE : View.GONE); + transitionEffectButton.setVisibility(pagedView.getPageCount() > 1 ? View.VISIBLE : View.GONE); widgetButton.setVisibility(!isAllAppsVisible() ? View.VISIBLE : View.GONE); wallpaperButton.setVisibility(!isAllAppsVisible() ? View.VISIBLE : View.GONE); sortButton.setVisibility(isAllAppsVisible() ? View.VISIBLE : View.GONE); diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index e982985f1..b70175ee8 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -47,12 +47,10 @@ import android.view.ViewParent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; -import android.view.animation.AnimationUtils; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; +import android.view.animation.*; import android.widget.Scroller; +import java.lang.reflect.Array; import java.util.ArrayList; interface Page { @@ -270,6 +268,17 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc protected int mFirstChildLeft; + private Runnable mDelayedSnapToPageRunnable; + + // Relating to the scroll and overscroll effects + protected static float CAMERA_DISTANCE = 6500; + protected static final float TRANSITION_SCALE_FACTOR = 0.74f; + protected static final float TRANSITION_SCREEN_ROTATION = 12.5f; + protected int mCameraDistance; + private boolean mScrollTransformsSet; + protected TransitionEffect mTransitionEffect; + protected boolean mUseTransitionEffect = true; + public interface PageSwitchListener { void onPageSwitch(View newPage, int newPageIndex); } @@ -597,6 +606,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc // a method that subclasses can override to add behavior protected void onPageEndMoving() { + if (mDelayedSnapToPageRunnable != null) { + mDelayedSnapToPageRunnable.run(); + mDelayedSnapToPageRunnable = null; + } } /** @@ -997,20 +1010,68 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } } + public TransitionEffect getTransitionEffect() { + return mTransitionEffect; + } + + public void setTransitionEffect(TransitionEffect effect) { + mTransitionEffect = effect; + + // Reset scroll transforms + if (mScrollTransformsSet) { + for (int i = 0; i < getChildCount(); i++) { + View v = getPageAt(i); + if (v != null) { + v.setPivotX(v.getMeasuredWidth() * 0.5f); + v.setPivotY(v.getMeasuredHeight() * 0.5f); + v.setRotation(0); + v.setRotationX(0); + v.setRotationY(0); + v.setScaleX(1f); + v.setScaleY(1f); + v.setTranslationX(0f); + v.setTranslationY(0f); + v.setVisibility(VISIBLE); + setChildAlpha(v, 1f); + } + } + + mScrollTransformsSet = false; + } + } + protected void screenScrolled(int screenCenter) { boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX; - - if (mFadeInAdjacentScreens && !isInOverscroll) { + // Apply transition effect and adjacent screen fade if enabled + if (mFadeInAdjacentScreens || (mTransitionEffect != null && mUseTransitionEffect) || mScrollTransformsSet) { for (int i = 0; i < getChildCount(); i++) { - View child = getChildAt(i); - if (child != null) { - float scrollProgress = getScrollProgress(screenCenter, child, i); - float alpha = 1 - Math.abs(scrollProgress); - child.setAlpha(alpha); + View v = getPageAt(i); + if (v != null) { + float scrollProgress = getScrollProgress(screenCenter, v, i); + // Fade first to allow transition effects to override alpha + if (mFadeInAdjacentScreens && !isInOverscroll) { + float alpha = 1 - Math.abs(scrollProgress); + setChildAlpha(v, alpha); + } + if (mTransitionEffect != null && mUseTransitionEffect && !isInOverscroll) { + mTransitionEffect.screenScrolled(v, i, scrollProgress); + } else if (mScrollTransformsSet) { + v.setPivotX(v.getMeasuredWidth() * 0.5f); + v.setPivotY(v.getMeasuredHeight() * 0.5f); + v.setRotation(0); + v.setRotationX(0); + v.setRotationY(0); + v.setScaleX(1f); + v.setScaleY(1f); + v.setTranslationX(0f); + v.setTranslationY(0f); + v.setVisibility(VISIBLE); + setChildAlpha(v, 1f); + } } } - invalidate(); } + mScrollTransformsSet = mTransitionEffect != null && mUseTransitionEffect && !isInOverscroll; } protected void enablePagedViewAnimations() { @@ -1021,6 +1082,42 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc mAllowPagedViewAnimations = false; } + /* + * This interpolator emulates the rate at which the perceived scale of an object changes + * as its distance from a camera increases. When this interpolator is applied to a scale + * animation on a view, it evokes the sense that the object is shrinking due to moving away + * from the camera. + */ + static class ZInterpolator implements TimeInterpolator { + private float focalLength; + + public ZInterpolator(float foc) { + focalLength = foc; + } + + public float getInterpolation(float input) { + return (1.0f - focalLength / (focalLength + input)) / + (1.0f - focalLength / (focalLength + 1.0f)); + } + } + + /* + * The exact reverse of ZInterpolator. + */ + static class InverseZInterpolator implements TimeInterpolator { + private ZInterpolator zInterpolator; + public InverseZInterpolator(float foc) { + zInterpolator = new ZInterpolator(foc); + } + public float getInterpolation(float input) { + return 1 - zInterpolator.getInterpolation(1 - input); + } + } + + protected void setChildAlpha(View child, float alpha) { + child.setAlpha(alpha); + } + @Override public void onChildViewAdded(View parent, View child) { // Update the page indicator, we don't update the page indicator as we @@ -2153,6 +2250,14 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc snapToPage(whichPage, delta, duration); } + protected void snapToPage(int whichPage, Runnable r) { + if (mDelayedSnapToPageRunnable != null) { + mDelayedSnapToPageRunnable.run(); + } + mDelayedSnapToPageRunnable = r; + snapToPage(whichPage, SLOW_PAGE_SNAP_ANIMATION_DURATION); + } + protected void snapToPage(int whichPage) { snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION); } @@ -2815,4 +2920,294 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc public boolean onHoverEvent(android.view.MotionEvent event) { return true; } + + protected static abstract class TransitionEffect { + public static final String TRANSITION_EFFECT_NONE = "none"; + public static final String TRANSITION_EFFECT_ZOOM_IN = "zoom-in"; + public static final String TRANSITION_EFFECT_ZOOM_OUT = "zoom-out"; + public static final String TRANSITION_EFFECT_ROTATE_UP = "rotate-up"; + public static final String TRANSITION_EFFECT_ROTATE_DOWN = "rotate-down"; + public static final String TRANSITION_EFFECT_CUBE_IN = "cube-in"; + public static final String TRANSITION_EFFECT_CUBE_OUT = "cube-out"; + public static final String TRANSITION_EFFECT_STACK = "stack"; + public static final String TRANSITION_EFFECT_ACCORDION = "accordion"; + public static final String TRANSITION_EFFECT_FLIP = "flip"; + public static final String TRANSITION_EFFECT_CYLINDER_IN = "cylinder-in"; + public static final String TRANSITION_EFFECT_CYLINDER_OUT = "cylinder-out"; + public static final String TRANSITION_EFFECT_CAROUSEL = "carousel"; + public static final String TRANSITION_EFFECT_OVERVIEW = "overview"; + + protected final PagedView mPagedView; + private final String mName; + + public TransitionEffect(PagedView pagedView, String name) { + mPagedView = pagedView; + mName = name; + } + + public abstract void screenScrolled(View v, int i, float scrollProgress); + + public final String getName() { + return mName; + } + + public static void setFromString(PagedView pagedView, String effect) { + if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_NONE)) { + pagedView.setTransitionEffect(null); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_ZOOM_IN)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Zoom(pagedView, true)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_ZOOM_OUT)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Zoom(pagedView, false)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_CUBE_IN)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Cube(pagedView, true)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_CUBE_OUT)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Cube(pagedView, false)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_ROTATE_UP)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Rotate(pagedView, true)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_ROTATE_DOWN)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Rotate(pagedView, false)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_STACK)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Stack(pagedView)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_ACCORDION)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Accordion(pagedView)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_FLIP)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Flip(pagedView)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_CYLINDER_IN)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Cylinder(pagedView, true)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_CYLINDER_OUT)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Cylinder(pagedView, false)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_CAROUSEL)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Carousel(pagedView)); + } else if (effect.equals(PagedView.TransitionEffect.TRANSITION_EFFECT_OVERVIEW)) { + pagedView.setTransitionEffect(new PagedView.TransitionEffect.Overview(pagedView)); + } + } + + public static class Zoom extends TransitionEffect { + private boolean mIn; + + public Zoom(PagedView pagedView, boolean in) { + super(pagedView, in ? TRANSITION_EFFECT_ZOOM_IN : TRANSITION_EFFECT_ZOOM_OUT); + mIn = in; + } + + @Override + public void screenScrolled(View v, int i, float scrollProgress) { + float scale = 1.0f + (mIn ? -0.2f : 0.1f) * Math.abs(scrollProgress); + + // Extra translation to account for the increase in size + if (!mIn) { + float translationX = v.getMeasuredWidth() * 0.1f * -scrollProgress; + v.setTranslationX(translationX); + } + + v.setScaleX(scale); + v.setScaleY(scale); + } + } + + public static class Rotate extends TransitionEffect { + private boolean mUp; + + public Rotate(PagedView pagedView, boolean up) { + super(pagedView, up ? TRANSITION_EFFECT_ROTATE_UP : TRANSITION_EFFECT_ROTATE_DOWN); + mUp = up; + } + + @Override + public void screenScrolled(View v, int i, float scrollProgress) { + float rotation = + (mUp ? TRANSITION_SCREEN_ROTATION : -TRANSITION_SCREEN_ROTATION) * scrollProgress; + + float translationX = v.getMeasuredWidth() * scrollProgress; + + float rotatePoint = + (v.getMeasuredWidth() * 0.5f) / + (float) Math.tan(Math.toRadians((double) (TRANSITION_SCREEN_ROTATION * 0.5f))); + + v.setPivotX(v.getMeasuredWidth() * 0.5f); + if (mUp) { + v.setPivotY(-rotatePoint); + } else { + v.setPivotY(v.getMeasuredHeight() + rotatePoint); + } + v.setRotation(rotation); + v.setTranslationX(translationX); + } + } + + public static class Cube extends TransitionEffect { + private boolean mIn; + + public Cube(PagedView pagedView, boolean in) { + super(pagedView, in ? TRANSITION_EFFECT_CUBE_IN : TRANSITION_EFFECT_CUBE_OUT); + mIn = in; + } + + @Override + public void screenScrolled(View v, int i, float scrollProgress) { + float rotation = (mIn ? 90.0f : -90.0f) * scrollProgress; + + if (mIn) { + v.setCameraDistance(mPagedView.mDensity * PagedView.CAMERA_DISTANCE); + } + + v.setPivotX(scrollProgress < 0 ? 0 : v.getMeasuredWidth()); + v.setPivotY(v.getMeasuredHeight() * 0.5f); + v.setRotationY(rotation); + } + } + + public static class Stack extends TransitionEffect { + private ZInterpolator mZInterpolator = new ZInterpolator(0.5f); + private DecelerateInterpolator mLeftScreenAlphaInterpolator = new DecelerateInterpolator(4); + protected AccelerateInterpolator mAlphaInterpolator = new AccelerateInterpolator(0.9f); + + public Stack(PagedView pagedView) { + super(pagedView, TRANSITION_EFFECT_STACK); + } + + @Override + public void screenScrolled(View v, int i, float scrollProgress) { + final boolean isRtl = mPagedView.isLayoutRtl(); + float interpolatedProgress; + float translationX; + float maxScrollProgress = Math.max(0, scrollProgress); + float minScrollProgress = Math.min(0, scrollProgress); + + if (mPagedView.isLayoutRtl()) { + translationX = maxScrollProgress * v.getMeasuredWidth(); + interpolatedProgress = mZInterpolator.getInterpolation(Math.abs(maxScrollProgress)); + } else { + translationX = minScrollProgress * v.getMeasuredWidth(); + interpolatedProgress = mZInterpolator.getInterpolation(Math.abs(minScrollProgress)); + } + float scale = (1 - interpolatedProgress) + + interpolatedProgress * TRANSITION_SCALE_FACTOR; + + float alpha; + if (isRtl && (scrollProgress > 0)) { + alpha = mAlphaInterpolator.getInterpolation(1 - Math.abs(maxScrollProgress)); + } else if (!isRtl && (scrollProgress < 0)) { + alpha = mAlphaInterpolator.getInterpolation(1 - Math.abs(scrollProgress)); + } else { + // On large screens we need to fade the page as it nears its leftmost position + alpha = mLeftScreenAlphaInterpolator.getInterpolation(1 - scrollProgress); + } + + v.setTranslationX(translationX); + v.setScaleX(scale); + v.setScaleY(scale); + if (v instanceof CellLayout) { + ((CellLayout) v).getShortcutsAndWidgets().setAlpha(alpha); + } else { + v.setAlpha(alpha); + } + + // If the view has 0 alpha, we set it to be invisible so as to prevent + // it from accepting touches + if (alpha == 0) { + v.setVisibility(INVISIBLE); + } else if (v.getVisibility() != VISIBLE) { + v.setVisibility(VISIBLE); + } + } + } + + public static class Accordion extends TransitionEffect { + public Accordion(PagedView pagedView) { + super(pagedView, TRANSITION_EFFECT_ACCORDION); + } + + @Override + public void screenScrolled(View v, int i, float scrollProgress) { + float scale = 1.0f - Math.abs(scrollProgress); + + v.setScaleX(scale); + v.setPivotX(scrollProgress < 0 ? 0 : v.getMeasuredWidth()); + v.setPivotY(v.getMeasuredHeight() / 2f); + } + } + + public static class Flip extends TransitionEffect { + public Flip(PagedView pagedView) { + super(pagedView, TRANSITION_EFFECT_FLIP); + } + + @Override + public void screenScrolled(View v, int i, float scrollProgress) { + float rotation = -180.0f * Math.max(-1f, Math.min(1f, scrollProgress)); + + v.setCameraDistance(mPagedView.mDensity * PagedView.CAMERA_DISTANCE); + v.setPivotX(v.getMeasuredWidth() * 0.5f); + v.setPivotY(v.getMeasuredHeight() * 0.5f); + v.setRotationY(rotation); + + if (scrollProgress >= -0.5f && scrollProgress <= 0.5f) { + v.setTranslationX(v.getMeasuredWidth() * scrollProgress); + if (v.getVisibility() != VISIBLE) { + v.setVisibility(VISIBLE); + } + } else { + v.setTranslationX(0f); + v.setVisibility(INVISIBLE); + } + } + } + + public static class Cylinder extends TransitionEffect { + private boolean mIn; + + public Cylinder(PagedView pagedView, boolean in) { + super(pagedView, in ? TRANSITION_EFFECT_CYLINDER_IN : TRANSITION_EFFECT_CYLINDER_OUT); + mIn = in; + } + + @Override + public void screenScrolled(View v, int i, float scrollProgress) { + float rotation = (mIn ? TRANSITION_SCREEN_ROTATION : -TRANSITION_SCREEN_ROTATION) * scrollProgress; + + v.setPivotX((scrollProgress + 1) * v.getMeasuredWidth() * 0.5f); + v.setPivotY(v.getMeasuredHeight() * 0.5f); + v.setRotationY(rotation); + } + } + + public static class Carousel extends TransitionEffect { + public Carousel(PagedView pagedView) { + super(pagedView, TRANSITION_EFFECT_CAROUSEL); + } + + @Override + public void screenScrolled(View v, int i, float scrollProgress) { + float rotation = 90.0f * scrollProgress; + + v.setCameraDistance(mPagedView.mDensity * PagedView.CAMERA_DISTANCE); + v.setTranslationX(v.getMeasuredWidth() * scrollProgress); + v.setPivotX(!mPagedView.isLayoutRtl() ? 0f : v.getMeasuredWidth()); + v.setPivotY(v.getMeasuredHeight() / 2); + v.setRotationY(-rotation); + } + } + + public static class Overview extends TransitionEffect { + private AccelerateDecelerateInterpolator mScaleInterpolator = new AccelerateDecelerateInterpolator(); + + public Overview(PagedView pagedView) { + super(pagedView, TRANSITION_EFFECT_OVERVIEW); + } + + @Override + public void screenScrolled(View v, int i, float scrollProgress) { + float scale = 1.0f - 0.1f * + mScaleInterpolator.getInterpolation(Math.min(0.3f, Math.abs(scrollProgress)) / 0.3f); + + v.setPivotX(scrollProgress < 0 ? 0 : v.getMeasuredWidth()); + v.setPivotY(v.getMeasuredHeight() * 0.5f); + v.setScaleX(scale); + v.setScaleY(scale); + mPagedView.setChildAlpha(v, scale); + } + } + } } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index f2a06e86c..ebe2e9af0 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -211,7 +211,7 @@ public class Workspace extends SmoothPagedView WallpaperOffsetInterpolator mWallpaperOffset; private boolean mScrollWallpaper; private Runnable mDelayedResizeRunnable; - private Runnable mDelayedSnapToPageRunnable; + private Point mDisplaySize = new Point(); private int mCameraDistance; @@ -316,6 +316,9 @@ public class Workspace extends SmoothPagedView mScrollWallpaper = SettingsProvider.getBoolean(context, SettingsProvider.SETTINGS_UI_HOMESCREEN_SCROLLING_WALLPAPER_SCROLL, R.bool.preferences_interface_homescreen_scrolling_wallpaper_scroll_default); + TransitionEffect.setFromString(this, SettingsProvider.getString(context, + SettingsProvider.SETTINGS_UI_HOMESCREEN_SCROLLING_TRANSITION_EFFECT, + R.string.preferences_interface_homescreen_scrolling_transition_effect)); mLauncher = (Launcher) context; final Resources res = getResources(); @@ -476,6 +479,11 @@ public class Workspace extends SmoothPagedView } @Override + public void setChildAlpha(View child, float alpha) { + ((CellLayout) child).setShortcutAndWidgetAlpha(alpha); + } + + @Override public void onChildViewAdded(View parent, View child) { if (!(child instanceof CellLayout)) { throw new IllegalArgumentException("A Workspace can only have CellLayout children."); @@ -1101,10 +1109,6 @@ public class Workspace extends SmoothPagedView mDelayedResizeRunnable = null; } - if (mDelayedSnapToPageRunnable != null) { - mDelayedSnapToPageRunnable.run(); - mDelayedSnapToPageRunnable = null; - } if (mStripScreensOnPageStopMoving) { stripEmptyScreens(); mStripScreensOnPageStopMoving = false; @@ -1147,14 +1151,6 @@ public class Workspace extends SmoothPagedView sp, mLauncher.getWindowManager(), mWallpaperManager); } - protected void snapToPage(int whichPage, Runnable r) { - if (mDelayedSnapToPageRunnable != null) { - mDelayedSnapToPageRunnable.run(); - } - mDelayedSnapToPageRunnable = r; - snapToPage(whichPage, SLOW_PAGE_SNAP_ANIMATION_DURATION); - } - protected void snapToScreenId(long screenId, Runnable r) { snapToPage(getPageIndexForScreenId(screenId), r); } @@ -1527,6 +1523,15 @@ public class Workspace extends SmoothPagedView @Override protected void screenScrolled(int screenCenter) { final boolean isRtl = isLayoutRtl(); + + boolean isOnLastPageBeforeCustomContent = false; + if (hasCustomContent()) { + int customContentWidth = mWorkspaceScreens.get(CUSTOM_CONTENT_SCREEN_ID).getMeasuredWidth(); + isOnLastPageBeforeCustomContent = (mOverScrollX < customContentWidth && (!hasCustomContent() || isLayoutRtl())) || + (mOverScrollX > mMaxScrollX - customContentWidth && (!hasCustomContent() || !isLayoutRtl())); + } + mUseTransitionEffect = !isOnLastPageBeforeCustomContent && mState == State.NORMAL && !mIsSwitchingState; + super.screenScrolled(screenCenter); updatePageAlphaValues(screenCenter); @@ -1783,38 +1788,6 @@ public class Workspace extends SmoothPagedView } /* - * This interpolator emulates the rate at which the perceived scale of an object changes - * as its distance from a camera increases. When this interpolator is applied to a scale - * animation on a view, it evokes the sense that the object is shrinking due to moving away - * from the camera. - */ - static class ZInterpolator implements TimeInterpolator { - private float focalLength; - - public ZInterpolator(float foc) { - focalLength = foc; - } - - public float getInterpolation(float input) { - return (1.0f - focalLength / (focalLength + input)) / - (1.0f - focalLength / (focalLength + 1.0f)); - } - } - - /* - * The exact reverse of ZInterpolator. - */ - static class InverseZInterpolator implements TimeInterpolator { - private ZInterpolator zInterpolator; - public InverseZInterpolator(float foc) { - zInterpolator = new ZInterpolator(foc); - } - public float getInterpolation(float input) { - return 1 - zInterpolator.getInterpolation(1 - input); - } - } - - /* * ZInterpolator compounded with an ease-out. */ static class ZoomOutInterpolator implements TimeInterpolator { @@ -2100,6 +2073,20 @@ public class Workspace extends SmoothPagedView float initialAlpha = cl.getShortcutsAndWidgets().getAlpha(); float finalAlpha = stateIsSmall ? 0f : 1f; + if (stateIsOverview) { + cl.setVisibility(VISIBLE); + cl.setTranslationX(0f); + cl.setTranslationY(0f); + cl.setPivotX(cl.getMeasuredWidth() * 0.5f); + cl.setPivotY(cl.getMeasuredHeight() * 0.5f); + cl.setRotation(0f); + cl.setRotationY(0f); + cl.setRotationX(0f); + cl.setScaleX(1f); + cl.setScaleY(1f); + cl.setShortcutAndWidgetAlpha(1f); + } + // If we are animating to/from the small state, then hide the side pages and fade the // current page in if (!mIsSwitchingState) { diff --git a/src/com/android/launcher3/settings/SettingsProvider.java b/src/com/android/launcher3/settings/SettingsProvider.java index 9c0a283ac..fb4c75056 100644 --- a/src/com/android/launcher3/settings/SettingsProvider.java +++ b/src/com/android/launcher3/settings/SettingsProvider.java @@ -26,8 +26,10 @@ public final class SettingsProvider { public static final String SETTINGS_UI_HOMESCREEN_DEFAULT_SCREEN_ID = "ui_homescreen_default_screen_id"; public static final String SETTINGS_UI_HOMESCREEN_SEARCH = "ui_homescreen_search"; + public static final String SETTINGS_UI_HOMESCREEN_SCROLLING_TRANSITION_EFFECT = "ui_homescreen_scrolling_transition_effect"; public static final String SETTINGS_UI_HOMESCREEN_SCROLLING_WALLPAPER_SCROLL = "ui_homescreen_scrolling_wallpaper_scroll"; public static final String SETTINGS_UI_HOMESCREEN_SCROLLING_PAGE_OUTLINES = "ui_homescreen_scrolling_page_outlines"; + public static final String SETTINGS_UI_DRAWER_SCROLLING_TRANSITION_EFFECT = "ui_drawer_scrolling_transition_effect"; public static final String SETTINGS_UI_GENERAL_ICONS_LARGE = "ui_general_icons_large"; public static final String SETTINGS_UI_GENERAL_ICONS_TEXT_FONT_FAMILY = "ui_general_icons_text_font"; public static final String SETTINGS_UI_GENERAL_ICONS_TEXT_FONT_STYLE = "ui_general_icons_text_font_style"; |