From 63f1ec00fbbd109130d1e476371dbc9a87bb544d Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Tue, 12 Aug 2014 09:23:13 -0700 Subject: [PATCH] Further refinement of all apps / widgets transition Change-Id: Id107a9aff74f014c07f8cbea6e74951a02dbddab --- res/layout/apps_customize_pane.xml | 17 ++- res/values/config.xml | 10 +- .../android/launcher3/AppsCustomizePagedView.java | 11 +- .../android/launcher3/AppsCustomizeTabHost.java | 2 +- src/com/android/launcher3/DeviceProfile.java | 13 +++ src/com/android/launcher3/Launcher.java | 124 ++++++++++++++------- src/com/android/launcher3/LauncherAnimUtils.java | 11 ++ src/com/android/launcher3/PagedView.java | 2 +- src/com/android/launcher3/Utilities.java | 21 ++++ src/com/android/launcher3/Workspace.java | 3 - 10 files changed, 156 insertions(+), 58 deletions(-) diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml index 03e433ac9..b1ba8d103 100644 --- a/res/layout/apps_customize_pane.xml +++ b/res/layout/apps_customize_pane.xml @@ -15,7 +15,8 @@ --> + xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3" + android:clipChildren="false"> + android:layout_weight="1" + android:clipChildren="false"> + android:layout_height="match_parent" + android:clipChildren="false" + android:clipToPadding="false"> + android:id="@+id/fake_page" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clipToPadding="false" /> 220 - 60 350 600 7 250 200 300 - 40 - 100 + + 250 + 60 + + + 17 0 diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java index e0543ceb6..2e81b9326 100644 --- a/src/com/android/launcher3/AppsCustomizePagedView.java +++ b/src/com/android/launcher3/AppsCustomizePagedView.java @@ -1003,8 +1003,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen Drawable bg = getContext().getResources().getDrawable(R.drawable.quantum_panel); if (bg != null) { + bg.setAlpha(mPageBackgroundsVisible ? 255: 0); layout.setBackground(bg); - bg.setVisible(mPageBackgroundsVisible, false); } setVisibilityOnChildren(layout, View.VISIBLE); @@ -1016,7 +1016,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen for (int i = 0; i < childCount; ++i) { Drawable bg = getChildAt(i).getBackground(); if (bg != null) { - bg.setVisible(visible, false); + bg.setAlpha(visible ? 255 : 0); } } } @@ -1163,7 +1163,12 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // immediately after syncing, we don't have a proper width. int widthSpec = MeasureSpec.makeMeasureSpec(mContentWidth, MeasureSpec.AT_MOST); int heightSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.AT_MOST); - layout.setBackground(getContext().getResources().getDrawable(R.drawable.quantum_panel_dark)); + + Drawable bg = getContext().getResources().getDrawable(R.drawable.quantum_panel_dark); + if (bg != null) { + bg.setAlpha(mPageBackgroundsVisible ? 255 : 0); + layout.setBackground(bg); + } layout.measure(widthSpec, heightSpec); } diff --git a/src/com/android/launcher3/AppsCustomizeTabHost.java b/src/com/android/launcher3/AppsCustomizeTabHost.java index 629bcdb1d..9a516fd41 100644 --- a/src/com/android/launcher3/AppsCustomizeTabHost.java +++ b/src/com/android/launcher3/AppsCustomizeTabHost.java @@ -174,7 +174,7 @@ public class AppsCustomizeTabHost extends FrameLayout implements LauncherTransit // Make sure the current page is loaded (we start loading the side pages after the // transition to prevent slowing down the animation) // TODO: revisit this - mPagedView.loadAssociatedPages(mPagedView.getCurrentPage(), true); + mPagedView.loadAssociatedPages(mPagedView.getCurrentPage()); } } diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 018fcfcbc..8af2a7fbb 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -126,6 +126,7 @@ public class DeviceProfile { int searchBarSpaceHeightPx; int searchBarHeightPx; int pageIndicatorHeightPx; + int allAppsButtonVisualSize; float dragViewScale; @@ -242,6 +243,18 @@ public class DeviceProfile { // Calculate the remaining vars updateFromConfiguration(context, res, wPx, hPx, awPx, ahPx); updateAvailableDimensions(context); + computeAllAppsButtonSize(context); + } + + /** + * Determine the exact visual footprint of the all apps button, taking into account scaling + * and internal padding of the drawable. + */ + private void computeAllAppsButtonSize(Context context) { + Resources res = context.getResources(); + float padding = res.getInteger(R.integer.config_allAppsButtonPaddingPercent) / 100f; + LauncherAppState app = LauncherAppState.getInstance(); + allAppsButtonVisualSize = (int) (hotseatIconSizePx * (1 - padding)); } void addCallback(DeviceProfileCallbacks cb) { diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 062e84838..31482f77e 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -242,6 +242,7 @@ public class Launcher extends Activity private static int NEW_APPS_PAGE_MOVE_DELAY = 500; private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5; private static int NEW_APPS_ANIMATION_DELAY = 500; + private static final int SINGLE_FRAME_DELAY = 16; private final BroadcastReceiver mCloseSystemDialogsReceiver = new CloseSystemDialogsIntentReceiver(); @@ -455,7 +456,6 @@ public class Launcher extends Activity Environment.getExternalStorageDirectory() + "/launcher"); } - checkForLocaleChange(); setContentView(R.layout.launcher); @@ -3223,8 +3223,6 @@ public class Launcher extends Activity final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor); final View fromView = mWorkspace; final AppsCustomizeTabHost toView = mAppsCustomizeTabHost; - final int startDelay = - res.getInteger(R.integer.config_workspaceAppsCustomizeAnimationStagger); Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ? Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN; @@ -3245,7 +3243,10 @@ public class Launcher extends Activity final View page = content.getPageAt(content.getCurrentPage()); final View revealView = toView.findViewById(R.id.fake_page); - if (contentType == AppsCustomizePagedView.ContentType.Widgets) { + final float initialPanelAlpha = 1f; + + final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets; + if (isWidgetTray) { revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark)); } else { revealView.setBackground(res.getDrawable(R.drawable.quantum_panel)); @@ -3259,15 +3260,21 @@ public class Launcher extends Activity int height = revealView.getMeasuredHeight(); float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4); - float yDrift = height / 2f; + revealView.setTranslationY(0); + // Get the y delta between the center of the page and the center of the all apps button + int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, + getAllAppsButton(), null); + float yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1]; + + float initAlpha = isWidgetTray ? 0.3f : 1f; revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null); - PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", 0.4f, 1f); + PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f); PropertyValuesHolder panelDrift = - PropertyValuesHolder.ofFloat("translationY", yDrift, 0f); + PropertyValuesHolder.ofFloat("translationY", yDrift, 0); ObjectAnimator panelAlphaAndDrift = - ObjectAnimator.ofPropertyValuesHolder(revealView, panelAlpha, panelDrift); + LauncherAnimUtils.ofPropertyValuesHolder(revealView, panelAlpha, panelDrift); panelAlphaAndDrift.setDuration(revealDuration); panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); @@ -3277,15 +3284,14 @@ public class Launcher extends Activity page.setVisibility(View.VISIBLE); page.setLayerType(View.LAYER_TYPE_HARDWARE, null); - ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0); + ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY", yDrift, 0); pageDrift.setDuration(revealDuration); pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); + pageDrift.setStartDelay(itemsAlphaStagger); mStateAnimation.play(pageDrift); - // TODO (adamcohen): remove this 0.01f hack once fw is fixed - // it's there to work around a framework bug (16918357) - page.setAlpha(0.01f); - ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0.01f, 1f); + page.setAlpha(0f); + ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 0f, 1f); itemsAlpha.setDuration(revealDuration); itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); itemsAlpha.setStartDelay(itemsAlphaStagger); @@ -3295,16 +3301,34 @@ public class Launcher extends Activity View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator); pageIndicators.setAlpha(0.01f); ObjectAnimator indicatorsAlpha = - ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f); + LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 1f); indicatorsAlpha.setDuration(revealDuration); mStateAnimation.play(indicatorsAlpha); if (material) { + final View allApps = getAllAppsButton(); + int allAppsButtonSize = LauncherAppState.getInstance(). + getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize; + float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2; ValueAnimator reveal = (ValueAnimator) - ViewAnimationUtils.createCircularReveal(revealView, width / 2, - height / 2, 0f, revealRadius); + LauncherAnimUtils.createCircularReveal(revealView, width / 2, + height / 2, startRadius, revealRadius); reveal.setDuration(revealDuration); reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); + + reveal.addListener(new AnimatorListenerAdapter() { + public void onAnimationStart(Animator animation) { + if (!isWidgetTray) { + allApps.setVisibility(View.INVISIBLE); + } + } + public void onAnimationEnd(Animator animation) { + if (!isWidgetTray) { + allApps.setVisibility(View.VISIBLE); + } + } + }); + mStateAnimation.play(reveal); } @@ -3413,12 +3437,11 @@ public class Launcher extends Activity } boolean material = Utilities.isLmp(); - Resources res = getResources(); final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime); final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime); - final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime); + final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime); final int itemsAlphaStagger = res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger); @@ -3428,9 +3451,8 @@ public class Launcher extends Activity final View toView = mWorkspace; Animator workspaceAnim = null; if (toState == Workspace.State.NORMAL) { - int stagger = res.getInteger(R.integer.config_appsCustomizeWorkspaceAnimationStagger); workspaceAnim = mWorkspace.getChangeStateAnimation( - toState, animated, stagger, -1); + toState, animated); } else if (toState == Workspace.State.SPRING_LOADED || toState == Workspace.State.OVERVIEW) { workspaceAnim = mWorkspace.getChangeStateAnimation( @@ -3448,7 +3470,9 @@ public class Launcher extends Activity final View revealView = fromView.findViewById(R.id.fake_page); AppsCustomizePagedView.ContentType contentType = content.getContentType(); - if (contentType == AppsCustomizePagedView.ContentType.Widgets) { + final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets; + + if (isWidgetTray) { revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark)); } else { revealView.setBackground(res.getDrawable(R.drawable.quantum_panel)); @@ -3462,34 +3486,43 @@ public class Launcher extends Activity revealView.setVisibility(View.VISIBLE); content.setPageBackgroundsVisible(false); - float yDrift = height / 2f; + final View allAppsButton = getAllAppsButton(); + revealView.setTranslationY(0); + int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, + allAppsButton, null); + float yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1]; revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null); - PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat(View.ALPHA, 1f, 0f); - PropertyValuesHolder panelDrift = - PropertyValuesHolder.ofFloat("translationY", 0, yDrift); - ObjectAnimator panelAlphaAndDrift = - ObjectAnimator.ofPropertyValuesHolder(revealView, panelAlpha, panelDrift); - panelAlphaAndDrift.setDuration(revealDuration); - - panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); - panelAlphaAndDrift.setStartDelay(itemsAlphaStagger); - - mStateAnimation.play(panelAlphaAndDrift); + // The vertical motion of the apps panel should be delayed by one frame + // from the conceal animation in order to give the right feel. We correpsondingly + // shorten the duration so that the slide and conceal end at the same time. + ObjectAnimator panelDrift = LauncherAnimUtils.ofFloat(revealView, "translationY", 0, yDrift); + panelDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); + panelDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); + panelDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); + mStateAnimation.play(panelDrift); + + if (isWidgetTray) { + ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha", 1f, 0.4f); + panelAlpha.setDuration(revealDuration); + panelAlpha.setInterpolator(new LogDecelerateInterpolator(100, 0)); + mStateAnimation.play(panelAlpha); + } if (page != null) { page.setLayerType(View.LAYER_TYPE_HARDWARE, null); - ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", 0, yDrift); - pageDrift.setDuration(revealDuration); + ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY", + 0, yDrift); + pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); - pageDrift.setStartDelay(itemsAlphaStagger); + pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); mStateAnimation.play(pageDrift); page.setAlpha(1f); - ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, View.ALPHA, 1f, 0f); - itemsAlpha.setDuration(revealDuration); + ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f); + itemsAlpha.setDuration(100); itemsAlpha.setInterpolator(new LogDecelerateInterpolator(100, 0)); mStateAnimation.play(itemsAlpha); } @@ -3497,7 +3530,7 @@ public class Launcher extends Activity View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator); pageIndicators.setAlpha(1f); ObjectAnimator indicatorsAlpha = - ObjectAnimator.ofFloat(pageIndicators, "alpha", 0f); + LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f); indicatorsAlpha.setDuration(revealDuration); indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f)); mStateAnimation.play(indicatorsAlpha); @@ -3505,9 +3538,15 @@ public class Launcher extends Activity width = revealView.getMeasuredWidth(); if (material) { + if (!isWidgetTray) { + allAppsButton.setVisibility(View.INVISIBLE); + } + int allAppsButtonSize = LauncherAppState.getInstance(). + getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize; + float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2; Animator reveal = - ViewAnimationUtils.createCircularReveal(revealView, width / 2, - height / 2 + 100, revealRadius, 0f); + LauncherAnimUtils.createCircularReveal(revealView, width / 2, + height / 2, revealRadius, finalRadius); reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); reveal.setDuration(revealDuration); reveal.setStartDelay(itemsAlphaStagger); @@ -3515,6 +3554,9 @@ public class Launcher extends Activity reveal.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator animation) { revealView.setVisibility(View.INVISIBLE); + if (!isWidgetTray) { + allAppsButton.setVisibility(View.VISIBLE); + } } }); diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java index e6c220b2a..be295f8b3 100644 --- a/src/com/android/launcher3/LauncherAnimUtils.java +++ b/src/com/android/launcher3/LauncherAnimUtils.java @@ -22,6 +22,7 @@ import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.view.View; +import android.view.ViewAnimationUtils; import android.view.ViewTreeObserver; import java.util.HashSet; @@ -126,4 +127,14 @@ public class LauncherAnimUtils { new FirstFrameAnimatorHelper(anim, view); return anim; } + + public static Animator createCircularReveal(View view, int centerX, + int centerY, float startRadius, float endRadius) { + Animator anim = ViewAnimationUtils.createCircularReveal(view, centerX, + centerY, startRadius, endRadius); + if (anim instanceof ValueAnimator) { + new FirstFrameAnimatorHelper((ValueAnimator) anim, view); + } + return anim; + } } diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 90a6b1598..cd0d55021 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -1159,7 +1159,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } protected boolean shouldDrawChild(View child) { - return child.getAlpha() > 0 && child.getVisibility() == VISIBLE; + return child.getVisibility() == VISIBLE; } @Override diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 60185c658..f70fc4d86 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -67,6 +67,8 @@ public final class Utilities { static int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff }; static int sColorIndex = 0; + static int[] sLoc0 = new int[2]; + static int[] sLoc1 = new int[2]; // To turn on these properties, type // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS] @@ -346,6 +348,25 @@ public final class Utilities { } } + public static int[] getCenterDeltaInScreenSpace(View v0, View v1, int[] delta) { + v0.getLocationInWindow(sLoc0); + v1.getLocationInWindow(sLoc1); + + sLoc0[0] += (v0.getMeasuredWidth() * v0.getScaleX()) / 2; + sLoc0[1] += (v0.getMeasuredHeight() * v0.getScaleY()) / 2; + sLoc1[0] += (v1.getMeasuredWidth() * v1.getScaleX()) / 2; + sLoc1[1] += (v1.getMeasuredHeight() * v1.getScaleY()) / 2; + + if (delta == null) { + delta = new int[2]; + } + + delta[0] = sLoc1[0] - sLoc0[0]; + delta[1] = sLoc1[1] - sLoc0[1]; + + return delta; + } + public static void scaleRectAboutCenter(Rect r, float scale) { int cx = r.centerX(); int cy = r.centerY(); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 8b3a51496..733923d24 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -2241,9 +2241,6 @@ public class Workspace extends SmoothPagedView } else if (stateIsOverview || stateIsOverviewHidden) { mNewScale = mOverviewModeShrinkFactor; } - if (workspaceToAllApps) { - updateChildrenLayersEnabled(false); - } } final int duration; -- 2.11.0