OSDN Git Service

Further refinement of all apps / widgets transition
authorAdam Cohen <adamcohen@google.com>
Tue, 12 Aug 2014 16:23:13 +0000 (09:23 -0700)
committerAdam Cohen <adamcohen@google.com>
Wed, 13 Aug 2014 21:39:48 +0000 (21:39 +0000)
Change-Id: Id107a9aff74f014c07f8cbea6e74951a02dbddab

res/layout/apps_customize_pane.xml
res/values/config.xml
src/com/android/launcher3/AppsCustomizePagedView.java
src/com/android/launcher3/AppsCustomizeTabHost.java
src/com/android/launcher3/DeviceProfile.java
src/com/android/launcher3/Launcher.java
src/com/android/launcher3/LauncherAnimUtils.java
src/com/android/launcher3/PagedView.java
src/com/android/launcher3/Utilities.java
src/com/android/launcher3/Workspace.java

index 03e433a..b1ba8d1 100644 (file)
@@ -15,7 +15,8 @@
 -->
 <com.android.launcher3.AppsCustomizeTabHost
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:clipChildren="false">
 
     <LinearLayout
         android:id="@+id/content"
         <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="0dp"
-            android:layout_weight="1">
+            android:layout_weight="1"
+            android:clipChildren="false">
             <FrameLayout
                 android:id="@+id/fake_page_container"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent" >
+                android:layout_height="match_parent"
+                android:clipChildren="false"
+                android:clipToPadding="false">
                 <FrameLayout
-                android:id="@+id/fake_page"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent" />
+                    android:id="@+id/fake_page"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:clipToPadding="false" />
             </FrameLayout>
             <com.android.launcher3.AppsCustomizePagedView
                 android:id="@+id/apps_customize_pane_content"
index 750a6aa..0da0b70 100644 (file)
     <!-- Fade/zoom in/out duration & scale in the AllApps transition.
          Note: This should be less than the workspaceShrinkTime as they happen together. -->
     <integer name="config_appsCustomizeRevealTime">220</integer>
-    <integer name="config_appsCustomizeItemsAlphaStagger">60</integer>
     <integer name="config_appsCustomizeZoomInTime">350</integer>
     <integer name="config_appsCustomizeZoomOutTime">600</integer>
     <integer name="config_appsCustomizeZoomScaleFactor">7</integer>
     <integer name="config_appsCustomizeFadeInTime">250</integer>
     <integer name="config_appsCustomizeFadeOutTime">200</integer>
     <integer name="config_appsCustomizeWorkspaceShrinkTime">300</integer>
-    <integer name="config_appsCustomizeWorkspaceAnimationStagger">40</integer>
-    <integer name="config_workspaceAppsCustomizeAnimationStagger">100</integer>
+
+    <integer name="config_appsCustomizeConcealTime">250</integer>
+    <integer name="config_appsCustomizeItemsAlphaStagger">60</integer>
+
+    <!-- This constant stores the ratio of the all apps button drawable which
+         is used for internal (baked-in) padding -->
+    <integer name="config_allAppsButtonPaddingPercent">17</integer>
 
     <integer name="config_workspaceDefaultScreen">0</integer>
 
index e0543ce..2e81b93 100644 (file)
@@ -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);
     }
 
index 629bcdb..9a516fd 100644 (file)
@@ -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());
         }
     }
 
index 018fcfc..8af2a7f 100644 (file)
@@ -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) {
index 062e848..31482f7 100644 (file)
@@ -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);
+                        }
                     }
                 });
 
index e6c220b..be295f8 100644 (file)
@@ -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;
+    }
 }
index 90a6b15..cd0d550 100644 (file)
@@ -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
index 60185c6..f70fc4d 100644 (file)
@@ -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();
index 8b3a514..733923d 100644 (file)
@@ -2241,9 +2241,6 @@ public class Workspace extends SmoothPagedView
             } else if (stateIsOverview || stateIsOverviewHidden) {
                 mNewScale = mOverviewModeShrinkFactor;
             }
-            if (workspaceToAllApps) {
-                updateChildrenLayersEnabled(false);
-            }
         }
 
         final int duration;