From b5e65c8bd3785409d4aeda21f2c88e75c9e22c9f Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 26 Oct 2016 18:32:38 -0700 Subject: Calling buildLayer only on views which are actually visible > Creating a common listener for handling buildLayer logic Bug: 30138067 Change-Id: I803ef78b48e07e5ae5922e0392d390f274a87d75 --- src/com/android/launcher3/Launcher.java | 3 +- .../LauncherStateTransitionAnimation.java | 120 +++------------------ src/com/android/launcher3/Workspace.java | 4 +- .../WorkspaceStateTransitionAnimation.java | 18 ++-- .../android/launcher3/anim/AnimationLayerSet.java | 53 +++++++++ 5 files changed, 81 insertions(+), 117 deletions(-) create mode 100644 src/com/android/launcher3/anim/AnimationLayerSet.java (limited to 'src/com/android') diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 40820fa9a..d870f9ee5 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -85,6 +85,7 @@ import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.allapps.DefaultAppSearchController; +import com.android.launcher3.anim.AnimationLayerSet; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.LauncherActivityInfoCompat; import com.android.launcher3.compat.LauncherAppsCompat; @@ -2954,7 +2955,7 @@ public class Launcher extends Activity * new state. */ public Animator startWorkspaceStateChangeAnimation(Workspace.State toState, - boolean animated, HashMap layerViews) { + boolean animated, AnimationLayerSet layerViews) { Workspace.State fromState = mWorkspace.getState(); Animator anim = mWorkspace.setStateWithAnimation(toState, animated, layerViews); updateInteraction(fromState, toState); diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java index 6d5f95159..7e842645b 100644 --- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java +++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java @@ -34,13 +34,12 @@ import android.view.animation.DecelerateInterpolator; import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.allapps.AllAppsTransitionController; +import com.android.launcher3.anim.AnimationLayerSet; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.CircleRevealOutlineProvider; import com.android.launcher3.util.Thunk; import com.android.launcher3.widget.WidgetsContainerView; -import java.util.HashMap; - /** * TODO: figure out what kind of tests we can write for this * @@ -119,9 +118,6 @@ public class LauncherStateTransitionAnimation { public static final String TAG = "LSTAnimation"; - // Flags to determine how to set the layers on views before the transition animation - public static final int BUILD_LAYER = 0; - public static final int BUILD_AND_SET_LAYER = 1; public static final int SINGLE_FRAME_DELAY = 16; @Thunk Launcher mLauncher; @@ -243,7 +239,7 @@ public class LauncherStateTransitionAnimation { final View fromView = mLauncher.getWorkspace(); - final HashMap layerViews = new HashMap<>(); + final AnimationLayerSet layerViews = new AnimationLayerSet(); // If for some reason our views aren't initialized, don't animate boolean initialized = buttonView != null; @@ -319,14 +315,14 @@ public class LauncherStateTransitionAnimation { panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); // Play the animation - layerViews.put(revealView, BUILD_AND_SET_LAYER); + layerViews.addView(revealView); animation.play(panelAlphaAndDrift); // Setup the animation for the content view contentView.setVisibility(View.VISIBLE); contentView.setAlpha(0f); contentView.setTranslationY(revealViewToYDrift); - layerViews.put(contentView, BUILD_AND_SET_LAYER); + layerViews.addView(contentView); // Create the individual animators ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", @@ -365,13 +361,6 @@ public class LauncherStateTransitionAnimation { // Hide the reveal view revealView.setVisibility(View.INVISIBLE); - // Disable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_NONE, null); - } - } - // This can hold unnecessary references to views. cleanupAnimation(); pCb.onTransitionComplete(); @@ -393,16 +382,6 @@ public class LauncherStateTransitionAnimation { dispatchOnLauncherTransitionStart(fromView, animated, false); dispatchOnLauncherTransitionStart(toView, animated, false); - // Enable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } - if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { - v.buildLayer(); - } - } - // Focus the new view toView.requestFocus(); @@ -411,25 +390,19 @@ public class LauncherStateTransitionAnimation { }; toView.bringToFront(); toView.setVisibility(View.VISIBLE); + + animation.addListener(layerViews); toView.post(startAnimRunnable); mCurrentAnimation = animation; } else if (animType == PULLUP) { // We are animating the content view alpha, so ensure we have a layer for it - layerViews.put(contentView, BUILD_AND_SET_LAYER); + layerViews.addView(contentView); animation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { dispatchOnLauncherTransitionEnd(fromView, animated, false); dispatchOnLauncherTransitionEnd(toView, animated, false); - - // Disable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_NONE, null); - } - } - cleanupAnimation(); pCb.onTransitionComplete(); } @@ -450,21 +423,12 @@ public class LauncherStateTransitionAnimation { dispatchOnLauncherTransitionStart(fromView, animated, false); dispatchOnLauncherTransitionStart(toView, animated, false); - // Enable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } - if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { - v.buildLayer(); - } - } - toView.requestFocus(); stateAnimation.start(); } }; mCurrentAnimation = animation; + mCurrentAnimation.addListener(layerViews); if (shouldPost) { toView.post(startAnimRunnable); } else { @@ -479,7 +443,7 @@ public class LauncherStateTransitionAnimation { private void playCommonTransitionAnimations( Workspace.State toWorkspaceState, View fromView, View toView, boolean animated, boolean initialized, AnimatorSet animation, - HashMap layerViews) { + AnimationLayerSet layerViews) { // Create the workspace animation. // NOTE: this call apparently also sets the state for the workspace if !animated Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, @@ -594,10 +558,8 @@ public class LauncherStateTransitionAnimation { final Workspace.State toWorkspaceState, final boolean animated, final Runnable onCompleteRunnable) { final View fromWorkspace = mLauncher.getWorkspace(); - final HashMap layerViews = new HashMap<>(); + final AnimationLayerSet layerViews = new AnimationLayerSet(); final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); - final int revealDuration = mLauncher.getResources() - .getInteger(R.integer.config_overlayRevealTime); // Cancel the current animation cancelAnimation(); @@ -622,16 +584,6 @@ public class LauncherStateTransitionAnimation { return; dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); - - // Enable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } - if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { - v.buildLayer(); - } - } stateAnimation.start(); } }; @@ -645,17 +597,11 @@ public class LauncherStateTransitionAnimation { onCompleteRunnable.run(); } - // Disable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_NONE, null); - } - } - // This can hold unnecessary references to views. cleanupAnimation(); } }); + stateAnimation.addListener(layerViews); fromWorkspace.post(startAnimRunnable); mCurrentAnimation = animation; } else /* if (!animated) */ { @@ -692,7 +638,7 @@ public class LauncherStateTransitionAnimation { final View revealView = fromView.getRevealView(); final View contentView = fromView.getContentView(); - final HashMap layerViews = new HashMap<>(); + final AnimationLayerSet layerViews = new AnimationLayerSet(); // If for some reason our views aren't initialized, don't animate boolean initialized = buttonView != null; @@ -735,7 +681,7 @@ public class LauncherStateTransitionAnimation { revealView.setVisibility(View.VISIBLE); revealView.setAlpha(1f); revealView.setTranslationY(0); - layerViews.put(revealView, BUILD_AND_SET_LAYER); + layerViews.addView(revealView); // Calculate the final animation values final float revealViewToXDrift; @@ -783,7 +729,7 @@ public class LauncherStateTransitionAnimation { } // Setup the animation for the content view - layerViews.put(contentView, BUILD_AND_SET_LAYER); + layerViews.addView(contentView); // Create the individual animators ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", @@ -843,13 +789,6 @@ public class LauncherStateTransitionAnimation { onCompleteRunnable.run(); } - // Disable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_NONE, null); - } - } - // Reset page transforms if (contentView != null) { contentView.setTranslationX(0); @@ -874,24 +813,15 @@ public class LauncherStateTransitionAnimation { dispatchOnLauncherTransitionStart(fromView, animated, false); dispatchOnLauncherTransitionStart(toView, animated, false); - - // Enable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } - if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { - v.buildLayer(); - } - } stateAnimation.start(); } }; mCurrentAnimation = animation; + mCurrentAnimation.addListener(layerViews); fromView.post(startAnimRunnable); } else if (animType == PULLUP) { // We are animating the content view alpha, so ensure we have a layer for it - layerViews.put(contentView, BUILD_AND_SET_LAYER); + layerViews.addView(contentView); animation.addListener(new AnimatorListenerAdapter() { boolean canceled = false; @@ -910,13 +840,6 @@ public class LauncherStateTransitionAnimation { onCompleteRunnable.run(); } - // Disable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_NONE, null); - } - } - cleanupAnimation(); pCb.onTransitionComplete(); } @@ -939,22 +862,13 @@ public class LauncherStateTransitionAnimation { dispatchOnLauncherTransitionStart(fromView, animated, false); dispatchOnLauncherTransitionStart(toView, animated, false); - // Enable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } - if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { - v.buildLayer(); - } - } - // Focus the new view toView.requestFocus(); stateAnimation.start(); } }; mCurrentAnimation = animation; + mCurrentAnimation.addListener(layerViews); if (shouldPost) { fromView.post(startAnimRunnable); } else { diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 3b9d6908d..173809342 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -60,6 +60,7 @@ import com.android.launcher3.accessibility.AccessibleDragListenerAdapter; import com.android.launcher3.accessibility.OverviewAccessibilityDelegate; import com.android.launcher3.accessibility.OverviewScreenAccessibilityDelegate; import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper; +import com.android.launcher3.anim.AnimationLayerSet; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.config.FeatureFlags; @@ -86,7 +87,6 @@ import com.android.launcher3.widget.PendingAddShortcutInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; /** @@ -2029,7 +2029,7 @@ public class Workspace extends PagedView * to that new state. */ public Animator setStateWithAnimation(State toState, boolean animated, - HashMap layerViews) { + AnimationLayerSet layerViews) { // Create the animation to the new state AnimatorSet workspaceAnim = mStateTransitionAnimation.getAnimationToState(mState, toState, animated, layerViews); diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index 598ba741a..1cf4b39f5 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -30,12 +30,11 @@ import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.DecelerateInterpolator; +import com.android.launcher3.anim.AnimationLayerSet; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.util.Thunk; -import java.util.HashMap; - /** * A convenience class to update a view's visibility state after an alpha animation. */ @@ -226,7 +225,7 @@ public class WorkspaceStateTransitionAnimation { } public AnimatorSet getAnimationToState(Workspace.State fromState, Workspace.State toState, - boolean animated, HashMap layerViews) { + boolean animated, AnimationLayerSet layerViews) { AccessibilityManager am = (AccessibilityManager) mLauncher.getSystemService(Context.ACCESSIBILITY_SERVICE); final boolean accessibilityEnabled = am.isEnabled(); @@ -262,8 +261,7 @@ public class WorkspaceStateTransitionAnimation { * Starts a transition animation for the workspace. */ private void animateWorkspace(final TransitionStates states, final boolean animated, - final int duration, final HashMap layerViews, - final boolean accessibilityEnabled) { + final int duration, AnimationLayerSet layerViews, final boolean accessibilityEnabled) { // Cancel existing workspace animations and create a new animator set if requested cancelAnimation(); if (animated) { @@ -396,12 +394,10 @@ public class WorkspaceStateTransitionAnimation { // For animation optimization, we may need to provide the Launcher transition // with a set of views on which to force build and manage layers in certain scenarios. - layerViews.put(overviewPanel, LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER); - layerViews.put(qsbContainer, LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER); - layerViews.put(mLauncher.getHotseat(), - LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER); - layerViews.put(mWorkspace.getPageIndicator(), - LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER); + layerViews.addView(overviewPanel); + layerViews.addView(qsbContainer); + layerViews.addView(mLauncher.getHotseat()); + layerViews.addView(mWorkspace.getPageIndicator()); if (states.workspaceToOverview) { hotseatAlpha.setInterpolator(new DecelerateInterpolator(2)); diff --git a/src/com/android/launcher3/anim/AnimationLayerSet.java b/src/com/android/launcher3/anim/AnimationLayerSet.java new file mode 100644 index 000000000..42706ffa1 --- /dev/null +++ b/src/com/android/launcher3/anim/AnimationLayerSet.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.anim; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.view.View; + +import java.util.HashSet; + +/** + * Helper class to automatically build view hardware layers for the duration of an animation. + */ +public class AnimationLayerSet extends AnimatorListenerAdapter { + + private final HashSet mViews = new HashSet<>(); + + public void addView(View v) { + mViews.add(v); + } + + @Override + public void onAnimationStart(Animator animation) { + // Enable all necessary layers + for (View v : mViews) { + v.setLayerType(View.LAYER_TYPE_HARDWARE, null); + if (v.isAttachedToWindow() && v.getVisibility() == View.VISIBLE) { + v.buildLayer(); + } + } + } + + @Override + public void onAnimationEnd(Animator animation) { + for (View v : mViews) { + v.setLayerType(View.LAYER_TYPE_NONE, null); + } + } +} -- cgit v1.2.3