From 35a4e0eec9986090a55567be40c4b269b2fe8985 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 18 Jun 2019 17:04:49 -0700 Subject: [PATCH] Tie prediction text to all apps interpolator Now floating headers get 2 interpolators: one for the header content itselt, and one for the all apps content that follows. That way, they can choose to intperolate part of their content as if it were part of all apps instead of the header. Currently, we do this to animate predicted icons quickly, followed by the all apps icons, predictions text, all apps scrollbar, and all apps divider as you continue swiping. Bug: 132455160 Change-Id: Ib3e373c291e174e1306a53854d0ad4dc29eb4b76 --- .../appprediction/AppsDividerView.java | 12 ++--- .../appprediction/PredictionRowView.java | 47 +++++++++++-------- .../FlingAndHoldTouchController.java | 12 +++++ .../PortraitStatesTouchController.java | 2 +- .../allapps/AllAppsTransitionController.java | 12 +++-- .../launcher3/allapps/FloatingHeaderRow.java | 4 +- .../launcher3/allapps/FloatingHeaderView.java | 18 +++---- .../launcher3/allapps/PluginHeaderRow.java | 6 +-- .../launcher3/anim/AnimatorSetBuilder.java | 1 + 9 files changed, 68 insertions(+), 46 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java index 311db21935..425fb13990 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java @@ -31,6 +31,9 @@ import android.util.AttributeSet; import android.view.View; import android.view.animation.Interpolator; +import androidx.annotation.ColorInt; +import androidx.core.content.ContextCompat; + import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; @@ -41,9 +44,6 @@ import com.android.launcher3.allapps.FloatingHeaderView; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.util.Themes; -import androidx.annotation.ColorInt; -import androidx.core.content.ContextCompat; - /** * A view which shows a horizontal divider */ @@ -288,10 +288,10 @@ public class AppsDividerView extends View implements LauncherStateManager.StateL } @Override - public void setContentVisibility(boolean hasHeaderExtra, boolean hasContent, - PropertySetter setter, Interpolator fadeInterpolator) { + public void setContentVisibility(boolean hasHeaderExtra, boolean hasAllAppsContent, + PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade) { // Don't use setViewAlpha as we want to control the visibility ourselves. - setter.setFloat(this, ALPHA, hasContent ? 1 : 0, fadeInterpolator); + setter.setFloat(this, ALPHA, hasAllAppsContent ? 1 : 0, allAppsFade); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java index cb5cbddd4a..b406bec829 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java @@ -32,6 +32,9 @@ import android.view.View; import android.view.animation.Interpolator; import android.widget.LinearLayout; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.android.launcher3.AppInfo; import com.android.launcher3.BubbleTextView; import com.android.launcher3.DeviceProfile; @@ -62,9 +65,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - @TargetApi(Build.VERSION_CODES.P) public class PredictionRowView extends LinearLayout implements LogContainerProvider, OnDeviceProfileChangeListener, FloatingHeaderRow { @@ -103,6 +103,8 @@ public class PredictionRowView extends LinearLayout implements private final int mIconTextColor; private final int mIconFullTextAlpha; + private int mIconLastSetTextAlpha; + // Might use mIconFullTextAlpha instead of mIconLastSetTextAlpha if we are translucent. private int mIconCurrentTextAlpha; private FloatingHeaderView mParent; @@ -315,14 +317,27 @@ public class PredictionRowView extends LinearLayout implements } } - public void setTextAlpha(int alpha) { - mIconCurrentTextAlpha = alpha; + public void setTextAlpha(int textAlpha) { + mIconLastSetTextAlpha = textAlpha; + if (getAlpha() < 1 && textAlpha > 0) { + // If the entire header is translucent, make sure the text is at full opacity so it's + // not double-translucent. However, we support keeping the text invisible (alpha == 0). + textAlpha = mIconFullTextAlpha; + } + mIconCurrentTextAlpha = textAlpha; int iconColor = setColorAlphaBound(mIconTextColor, mIconCurrentTextAlpha); for (int i = 0; i < getChildCount(); i++) { ((BubbleTextView) getChildAt(i)).setTextColor(iconColor); } } + @Override + public void setAlpha(float alpha) { + super.setAlpha(alpha); + // Reapply text alpha so that we update it to be full alpha if the row is now translucent. + setTextAlpha(mIconLastSetTextAlpha); + } + @Override public boolean hasOverlappingRendering() { return false; @@ -351,23 +366,15 @@ public class PredictionRowView extends LinearLayout implements } @Override - public void setContentVisibility(boolean hasHeaderExtra, boolean hasContent, - PropertySetter setter, Interpolator fadeInterpolator) { - boolean isDrawn = getAlpha() > 0; - int textAlpha = hasHeaderExtra - ? (hasContent ? mIconFullTextAlpha : 0) // Text follows the content visibility - : mIconCurrentTextAlpha; // Leave as before - if (!isDrawn) { - // If the header is not drawn, no need to animate the text alpha - setTextAlpha(textAlpha); - } else { - setter.setInt(this, TEXT_ALPHA, textAlpha, fadeInterpolator); - } - + public void setContentVisibility(boolean hasHeaderExtra, boolean hasAllAppsContent, + PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade) { + // Text follows all apps visibility + int textAlpha = hasHeaderExtra && hasAllAppsContent ? mIconFullTextAlpha : 0; + setter.setInt(this, TEXT_ALPHA, textAlpha, allAppsFade); setter.setFloat(mOverviewScrollFactor, AnimatedFloat.VALUE, - (hasHeaderExtra && !hasContent) ? 1 : 0, LINEAR); + (hasHeaderExtra && !hasAllAppsContent) ? 1 : 0, LINEAR); setter.setFloat(mContentAlphaFactor, AnimatedFloat.VALUE, hasHeaderExtra ? 1 : 0, - fadeInterpolator); + headerFade); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java index 6142cdfc10..ab346c0599 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java @@ -23,13 +23,17 @@ import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_PEEK; import static com.android.launcher3.LauncherStateManager.ANIM_ALL; import static com.android.launcher3.LauncherStateManager.ATOMIC_OVERVIEW_PEEK_COMPONENT; +import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE; +import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_HEADER_FADE; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_SCALE; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_TRANSLATE; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_SCALE; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_TRANSLATE; +import static com.android.launcher3.anim.Interpolators.ACCEL; import static com.android.launcher3.anim.Interpolators.DEACCEL_3; +import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; @@ -43,6 +47,7 @@ import android.view.ViewConfiguration; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.anim.AnimatorSetBuilder; +import com.android.launcher3.anim.Interpolators; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.quickstep.OverviewInteractionState; import com.android.quickstep.util.MotionPauseDetector; @@ -123,6 +128,13 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController { LauncherState toState) { if (fromState == NORMAL && toState == ALL_APPS) { AnimatorSetBuilder builder = new AnimatorSetBuilder(); + // Fade in prediction icons quickly, then rest of all apps after reaching overview. + float progressToReachOverview = NORMAL.getVerticalProgress(mLauncher) + - OVERVIEW.getVerticalProgress(mLauncher); + builder.setInterpolator(ANIM_ALL_APPS_HEADER_FADE, Interpolators.clampToProgress(ACCEL, + 0, ALL_APPS_CONTENT_FADE_THRESHOLD)); + builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(LINEAR, + progressToReachOverview, 1)); // Get workspace out of the way quickly, to prepare for potential pause. builder.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL_3); diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java index 109d751c48..a55f36b787 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java @@ -62,7 +62,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr /** * The progress at which all apps content will be fully visible when swiping up from overview. */ - private static final float ALL_APPS_CONTENT_FADE_THRESHOLD = 0.08f; + protected static final float ALL_APPS_CONTENT_FADE_THRESHOLD = 0.08f; /** * The progress at which recents will begin fading out when swiping up from overview. diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index a64374bc37..5b3beeca7f 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -7,6 +7,7 @@ import static com.android.launcher3.LauncherState.HOTSEAT_ICONS; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.VERTICAL_SWIPE_INDICATOR; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE; +import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_HEADER_FADE; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; @@ -208,13 +209,14 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil PropertySetter setter = config == null ? NO_ANIM_PROPERTY_SETTER : config.getPropertySetter(builder); boolean hasHeaderExtra = (visibleElements & ALL_APPS_HEADER_EXTRA) != 0; - boolean hasContent = (visibleElements & ALL_APPS_CONTENT) != 0; + boolean hasAllAppsContent = (visibleElements & ALL_APPS_CONTENT) != 0; Interpolator allAppsFade = builder.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR); - setter.setViewAlpha(mAppsView.getContentView(), hasContent ? 1 : 0, allAppsFade); - setter.setViewAlpha(mAppsView.getScrollBar(), hasContent ? 1 : 0, allAppsFade); - mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasContent, setter, - allAppsFade); + Interpolator headerFade = builder.getInterpolator(ANIM_ALL_APPS_HEADER_FADE, allAppsFade); + setter.setViewAlpha(mAppsView.getContentView(), hasAllAppsContent ? 1 : 0, allAppsFade); + setter.setViewAlpha(mAppsView.getScrollBar(), hasAllAppsContent ? 1 : 0, allAppsFade); + mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasAllAppsContent, + setter, headerFade, allAppsFade); mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade); setter.setInt(mScrimView, ScrimView.DRAG_HANDLE_ALPHA, diff --git a/src/com/android/launcher3/allapps/FloatingHeaderRow.java b/src/com/android/launcher3/allapps/FloatingHeaderRow.java index 922e4f1a3f..f899587bc0 100644 --- a/src/com/android/launcher3/allapps/FloatingHeaderRow.java +++ b/src/com/android/launcher3/allapps/FloatingHeaderRow.java @@ -46,8 +46,8 @@ public interface FloatingHeaderRow { */ boolean hasVisibleContent(); - void setContentVisibility(boolean hasHeaderExtra, boolean hasContent, - PropertySetter setter, Interpolator fadeInterpolator); + void setContentVisibility(boolean hasHeaderExtra, boolean hasAllAppsContent, + PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade); /** * Scrolls the content vertically. diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java index 66dced99d3..42a0eee77c 100644 --- a/src/com/android/launcher3/allapps/FloatingHeaderView.java +++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java @@ -27,6 +27,10 @@ import android.view.ViewGroup; import android.view.animation.Interpolator; import android.widget.LinearLayout; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; import com.android.launcher3.Launcher; @@ -40,10 +44,6 @@ import com.android.systemui.plugins.PluginListener; import java.util.ArrayList; import java.util.Map; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.RecyclerView; - public class FloatingHeaderView extends LinearLayout implements ValueAnimator.AnimatorUpdateListener, PluginListener, Insettable, OnHeightUpdatedListener { @@ -363,14 +363,14 @@ public class FloatingHeaderView extends LinearLayout implements p.y = getTop() - mCurrentRV.getTop() - mParent.getTop(); } - public void setContentVisibility(boolean hasHeader, boolean hasContent, PropertySetter setter, - Interpolator fadeInterpolator) { + public void setContentVisibility(boolean hasHeader, boolean hasAllAppsContent, + PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade) { for (FloatingHeaderRow row : mAllRows) { - row.setContentVisibility(hasHeader, hasContent, setter, fadeInterpolator); + row.setContentVisibility(hasHeader, hasAllAppsContent, setter, headerFade, allAppsFade); } - allowTouchForwarding(hasContent); - setter.setFloat(mTabLayout, ALPHA, hasContent ? 1 : 0, fadeInterpolator); + allowTouchForwarding(hasAllAppsContent); + setter.setFloat(mTabLayout, ALPHA, hasAllAppsContent ? 1 : 0, headerFade); } protected void allowTouchForwarding(boolean allow) { diff --git a/src/com/android/launcher3/allapps/PluginHeaderRow.java b/src/com/android/launcher3/allapps/PluginHeaderRow.java index b283ff4056..535ef54bc9 100644 --- a/src/com/android/launcher3/allapps/PluginHeaderRow.java +++ b/src/com/android/launcher3/allapps/PluginHeaderRow.java @@ -64,10 +64,10 @@ public class PluginHeaderRow implements FloatingHeaderRow { } @Override - public void setContentVisibility(boolean hasHeaderExtra, boolean hasContent, - PropertySetter setter, Interpolator fadeInterpolator) { + public void setContentVisibility(boolean hasHeaderExtra, boolean hasAllAppsContent, + PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade) { // Don't use setViewAlpha as we want to control the visibility ourselves. - setter.setFloat(mView, ALPHA, hasContent ? 1 : 0, fadeInterpolator); + setter.setFloat(mView, ALPHA, hasAllAppsContent ? 1 : 0, headerFade); } @Override diff --git a/src/com/android/launcher3/anim/AnimatorSetBuilder.java b/src/com/android/launcher3/anim/AnimatorSetBuilder.java index 11db25be44..cd30dea9c0 100644 --- a/src/com/android/launcher3/anim/AnimatorSetBuilder.java +++ b/src/com/android/launcher3/anim/AnimatorSetBuilder.java @@ -40,6 +40,7 @@ public class AnimatorSetBuilder { public static final int ANIM_OVERVIEW_FADE = 9; public static final int ANIM_ALL_APPS_FADE = 10; public static final int ANIM_OVERVIEW_SCRIM_FADE = 11; + public static final int ANIM_ALL_APPS_HEADER_FADE = 12; // e.g. predictions public static final int FLAG_DONT_ANIMATE_OVERVIEW = 1 << 0;