diff options
Diffstat (limited to 'src/com/android/launcher3/allapps')
8 files changed, 158 insertions, 30 deletions
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index ae41794ad..f8648bba0 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -15,8 +15,6 @@ */ package com.android.launcher3.allapps; -import static com.android.launcher3.anim.Interpolators.DEACCEL_2; - import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; @@ -47,8 +45,8 @@ import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.graphics.ColorScrim; import com.android.launcher3.keyboard.FocusedItemDecorator; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.ItemInfoMatcher; @@ -111,10 +109,6 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo mAllAppsStore.addUpdateListener(this::onAppsUpdated); - // Attach a scrim to be drawn behind all-apps and hotseat - new ColorScrim(this, Themes.getAttrColor(context, R.attr.allAppsScrimColor), DEACCEL_2) - .attach(); - addSpringView(R.id.all_apps_header); addSpringView(R.id.apps_list_view); addSpringView(R.id.all_apps_tabs_view_pager); @@ -125,6 +119,13 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo } @Override + protected void setDampedScrollShift(float shift) { + // Bound the shift amount to avoid content from drawing on top (Y-val) of the QSB. + float maxShift = getSearchView().getHeight() / 2f; + super.setDampedScrollShift(Utilities.boundToRange(shift, -maxShift, maxShift)); + } + + @Override public void onDeviceProfileChanged(DeviceProfile dp) { for (AdapterHolder holder : mAH) { if (holder.recyclerView != null) { diff --git a/src/com/android/launcher3/allapps/AllAppsPagedView.java b/src/com/android/launcher3/allapps/AllAppsPagedView.java index b2e35a473..69068c6ee 100644 --- a/src/com/android/launcher3/allapps/AllAppsPagedView.java +++ b/src/com/android/launcher3/allapps/AllAppsPagedView.java @@ -76,4 +76,9 @@ public class AllAppsPagedView extends PagedView<PersonalWorkSlidingTabStrip> { super.determineScrollingStart(ev); } } + + @Override + public boolean hasOverlappingRendering() { + return false; + } } diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index a7447b7b8..a6c1346f6 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -415,4 +415,8 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine y + mEmptySearchBackground.getIntrinsicHeight()); } + @Override + public boolean hasOverlappingRendering() { + return false; + } } diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index ed9873eaf..b5c821ac2 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -3,6 +3,8 @@ package com.android.launcher3.allapps; import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT; import static com.android.launcher3.LauncherState.ALL_APPS_HEADER; import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA; +import static com.android.launcher3.LauncherState.OVERVIEW; +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; import static com.android.launcher3.anim.Interpolators.LINEAR; @@ -23,10 +25,13 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.LauncherStateManager.StateHandler; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; +import com.android.launcher3.uioverrides.UiFactory; import com.android.launcher3.util.Themes; +import com.android.launcher3.views.ScrimView; /** * Handles AllApps view transition. @@ -55,6 +60,7 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil }; private AllAppsContainerView mAppsView; + private ScrimView mScrimView; private final Launcher mLauncher; private final boolean mIsDarkTheme; @@ -99,7 +105,6 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil mAppsView.setAlpha(1); mLauncher.getHotseat().setTranslationY(0); mLauncher.getWorkspace().getPageIndicator().setTranslationY(0); - mLauncher.getDragHandleIndicator().setTranslationY(0); } } @@ -114,6 +119,7 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil */ public void setProgress(float progress) { mProgress = progress; + mScrimView.setProgress(progress); float shiftCurrent = progress * mShiftRange; mAppsView.setTranslationY(shiftCurrent); @@ -122,12 +128,12 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil if (!mIsVerticalLayout) { mLauncher.getHotseat().setTranslationY(hotseatTranslation); mLauncher.getWorkspace().getPageIndicator().setTranslationY(hotseatTranslation); - mLauncher.getDragHandleIndicator().setTranslationY(hotseatTranslation); } // Use a light system UI (dark icons) if all apps is behind at least half of the // status bar. - boolean forceChange = shiftCurrent <= mShiftRange / 4; + boolean forceChange = shiftCurrent - mScrimView.getDragHandleSize() + <= mLauncher.getDeviceProfile().getInsets().top / 2; if (forceChange) { mLauncher.getSystemUiController().updateUiState(UI_STATE_ALL_APPS, !mIsDarkTheme); } else { @@ -159,22 +165,36 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil AnimatorSetBuilder builder, AnimationConfig config) { float targetProgress = toState.getVerticalProgress(mLauncher); if (Float.compare(mProgress, targetProgress) == 0) { - setAlphas(toState, config.getProperSetter(builder)); + setAlphas(toState, config.getPropertySetter(builder)); // Fail fast onProgressAnimationEnd(); return; } - Interpolator interpolator = config.userControlled ? LINEAR : FAST_OUT_SLOW_IN; + if (!config.playNonAtomicComponent()) { + // There is no atomic component for the all apps transition, so just return early. + return; + } + + Interpolator interpolator = config.userControlled ? LINEAR : toState == OVERVIEW + ? builder.getInterpolator(ANIM_OVERVIEW_SCALE, FAST_OUT_SLOW_IN) + : FAST_OUT_SLOW_IN; ObjectAnimator anim = ObjectAnimator.ofFloat(this, ALL_APPS_PROGRESS, mProgress, targetProgress); anim.setDuration(config.duration); anim.setInterpolator(builder.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator)); anim.addListener(getProgressAnimatorListener()); + if (toState.hideBackButton) { + anim.addUpdateListener(animation -> { + final float alpha = (float) animation.getAnimatedValue(); + UiFactory.setBackButtonAlpha(mLauncher, 1 - Utilities.boundToRange(alpha, 0, 1), + false /* animate */); + }); + } builder.play(anim); - setAlphas(toState, config.getProperSetter(builder)); + setAlphas(toState, config.getPropertySetter(builder)); } private void setAlphas(LauncherState toState, PropertySetter setter) { @@ -205,6 +225,7 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil public void setupViews(AllAppsContainerView appsView) { mAppsView = appsView; + mScrimView = mLauncher.findViewById(R.id.scrim_view); } /** @@ -213,6 +234,10 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil public void setScrollRangeDelta(float delta) { mScrollRangeDelta = delta; mShiftRange = mLauncher.getDeviceProfile().heightPx - mScrollRangeDelta; + + if (mScrimView != null) { + mScrimView.reInitUi(); + } } /** diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java index fddafb2a6..e1cd06a8b 100644 --- a/src/com/android/launcher3/allapps/DiscoveryBounce.java +++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2018 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. @@ -17,35 +17,46 @@ package com.android.launcher3.allapps; import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.LauncherState.OVERVIEW; +import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.HOTSEAT; +import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.PREDICTION; import android.animation.Animator; import android.animation.AnimatorInflater; import android.animation.AnimatorListenerAdapter; +import android.animation.Keyframe; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.animation.TimeInterpolator; import android.app.ActivityManager; -import android.content.Context; +import android.os.Handler; import android.view.MotionEvent; +import android.view.animation.PathInterpolator; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.states.InternalStateHandler; /** - * Floating view responsible for showing discovery bounce animation + * Abstract base class of floating view responsible for showing discovery bounce animation */ public class DiscoveryBounce extends AbstractFloatingView { - public static final String APPS_VIEW_SHOWN = "launcher.apps_view_shown"; + private static final long DELAY_MS = 450; + + public static final String HOME_BOUNCE_SEEN = "launcher.apps_view_shown"; + public static final String SHELF_BOUNCE_SEEN = "launcher.shelf_bounce_seen"; private final Launcher mLauncher; private final Animator mDiscoBounceAnimation; - public DiscoveryBounce(Launcher launcher) { + public DiscoveryBounce(Launcher launcher, Animator animator) { super(launcher, null); mLauncher = launcher; - mDiscoBounceAnimation = AnimatorInflater.loadAnimator(mLauncher, - R.animator.discovery_bounce); + mDiscoBounceAnimation = animator; AllAppsTransitionController controller = mLauncher.getAllAppsController(); mDiscoBounceAnimation.setTarget(controller); mDiscoBounceAnimation.addListener(controller.getProgressAnimatorListener()); @@ -73,6 +84,14 @@ public class DiscoveryBounce extends AbstractFloatingView { } @Override + public boolean onBackPressed() { + super.onBackPressed(); + // Go back to the previous state (from a user's perspective this floating view isn't + // something to go back from). + return false; + } + + @Override public boolean onControllerInterceptTouchEvent(MotionEvent ev) { handleClose(false); return false; @@ -96,17 +115,75 @@ public class DiscoveryBounce extends AbstractFloatingView { return (type & TYPE_ON_BOARD_POPUP) != 0; } - public static void showIfNeeded(Launcher launcher) { + public static void showForHomeIfNeeded(Launcher launcher) { + showForHomeIfNeeded(launcher, true); + } + + private static void showForHomeIfNeeded(Launcher launcher, boolean withDelay) { if (!launcher.isInState(NORMAL) - || launcher.getSharedPrefs().getBoolean(APPS_VIEW_SHOWN, false) + || launcher.getSharedPrefs().getBoolean(HOME_BOUNCE_SEEN, false) || AbstractFloatingView.getTopOpenView(launcher) != null || UserManagerCompat.getInstance(launcher).isDemoUser() || ActivityManager.isRunningInTestHarness()) { return; } - DiscoveryBounce view = new DiscoveryBounce(launcher); + if (withDelay) { + new Handler().postDelayed(() -> showForHomeIfNeeded(launcher, false), DELAY_MS); + return; + } + + DiscoveryBounce view = new DiscoveryBounce(launcher, + AnimatorInflater.loadAnimator(launcher, R.animator.discovery_bounce)); + view.mIsOpen = true; + launcher.getDragLayer().addView(view); + launcher.getUserEventDispatcher().logActionBounceTip(HOTSEAT); + } + + public static void showForOverviewIfNeeded(Launcher launcher) { + showForOverviewIfNeeded(launcher, true); + } + + private static void showForOverviewIfNeeded(Launcher launcher, boolean withDelay) { + if (!launcher.isInState(OVERVIEW) + || !launcher.hasBeenResumed() + || launcher.isForceInvisible() + || launcher.getDeviceProfile().isVerticalBarLayout() + || launcher.getSharedPrefs().getBoolean(SHELF_BOUNCE_SEEN, false) + || UserManagerCompat.getInstance(launcher).isDemoUser() + || ActivityManager.isRunningInTestHarness()) { + return; + } + + if (withDelay) { + new Handler().postDelayed(() -> showForOverviewIfNeeded(launcher, false), DELAY_MS); + return; + } else if (InternalStateHandler.hasPending() + || AbstractFloatingView.getTopOpenView(launcher) != null) { + // TODO: Move these checks to the top and call this method after invalidate handler. + return; + } + + float verticalProgress = OVERVIEW.getVerticalProgress(launcher); + + TimeInterpolator pathInterpolator = new PathInterpolator(0.35f, 0, 0.5f, 1); + Keyframe keyframe3 = Keyframe.ofFloat(0.423f, verticalProgress - (1 - 0.9738f)); + keyframe3.setInterpolator(pathInterpolator); + Keyframe keyframe4 = Keyframe.ofFloat(0.754f, verticalProgress); + keyframe4.setInterpolator(pathInterpolator); + + PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofKeyframe("progress", + Keyframe.ofFloat(0, verticalProgress), + Keyframe.ofFloat(0.246f, verticalProgress), keyframe3, keyframe4, + Keyframe.ofFloat(1f, verticalProgress)); + ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(null, + new PropertyValuesHolder[]{propertyValuesHolder}); + animator.setDuration(2166); + animator.setRepeatCount(5); + + DiscoveryBounce view = new DiscoveryBounce(launcher, animator); view.mIsOpen = true; launcher.getDragLayer().addView(view); + launcher.getUserEventDispatcher().logActionBounceTip(PREDICTION); } } diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java index 461f5b5ba..462e7f34e 100644 --- a/src/com/android/launcher3/allapps/FloatingHeaderView.java +++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java @@ -74,6 +74,7 @@ public class FloatingHeaderView extends LinearLayout implements protected boolean mTabsHidden; protected int mMaxTranslation; + private boolean mMainRVActive = true; public FloatingHeaderView(@NonNull Context context) { this(context, null); @@ -95,7 +96,7 @@ public class FloatingHeaderView extends LinearLayout implements mMainRV = setupRV(mMainRV, mAH[AllAppsContainerView.AdapterHolder.MAIN].recyclerView); mWorkRV = setupRV(mWorkRV, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView); mParent = (ViewGroup) mMainRV.getParent(); - setMainActive(true); + setMainActive(mMainRVActive || mWorkRV == null); reset(false); } @@ -108,6 +109,7 @@ public class FloatingHeaderView extends LinearLayout implements public void setMainActive(boolean active) { mCurrentRV = active ? mMainRV : mWorkRV; + mMainRVActive = active; } public int getMaxTranslation() { @@ -237,6 +239,11 @@ public class FloatingHeaderView extends LinearLayout implements public boolean hasVisibleContent() { return false; } + + @Override + public boolean hasOverlappingRendering() { + return false; + } } diff --git a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java index a069d5d4d..a916697bf 100644 --- a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java +++ b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java @@ -25,6 +25,7 @@ import android.util.AttributeSet; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; + import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -169,8 +170,7 @@ public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageInd public void setMarkersCount(int numMarkers) { } @Override - public void setPageDescription(CharSequence description) { - // We don't want custom page description as the tab-bar already has two tabs with their - // own descriptions. + public boolean hasOverlappingRendering() { + return false; } } diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java index ad61c55db..ab6635e45 100644 --- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java +++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java @@ -62,6 +62,10 @@ public class AppsSearchContainerLayout extends ExtendedEditText private AlphabeticalAppsList mApps; private AllAppsContainerView mAppsView; + // This value was used to position the QSB. We store it here for translationY animations. + private final float mFixedTranslationY; + private final float mMarginTopAdjusting; + public AppsSearchContainerLayout(Context context) { this(context, null); } @@ -79,6 +83,9 @@ public class AppsSearchContainerLayout extends ExtendedEditText mSearchQueryBuilder = new SpannableStringBuilder(); Selection.setSelection(mSearchQueryBuilder, 0); + mFixedTranslationY = getTranslationY(); + mMarginTopAdjusting = mFixedTranslationY - getPaddingTop(); + // Update the hint to contain the icon. // Prefix the original hint with two spaces. The first space gets replaced by the icon // using span. The second space is used for a singe space character between the hint @@ -195,14 +202,16 @@ public class AppsSearchContainerLayout extends ExtendedEditText @Override public void setInsets(Rect insets) { + MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams(); + mlp.topMargin = Math.round(Math.max(-mFixedTranslationY, insets.top - mMarginTopAdjusting)); + requestLayout(); + DeviceProfile dp = mLauncher.getDeviceProfile(); if (dp.isVerticalBarLayout()) { mLauncher.getAllAppsController().setScrollRangeDelta(0); } else { - MarginLayoutParams mlp = ((MarginLayoutParams) getLayoutParams()); - int myBot = mlp.topMargin + (int) getTranslationY() + mlp.height; mLauncher.getAllAppsController().setScrollRangeDelta( - dp.hotseatBarBottomPaddingPx + myBot); + insets.bottom + mlp.topMargin + mFixedTranslationY); } } } |