mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-04 09:56:49 +00:00
Add floatingMaskView when animating to mimic bottom container.
- On expand, we add the floating mask view and translate it out at the end. - On collapse, we translate off the mask view in the beginning once the floating mask view is added so that we can translate it in before the actual collapsing part of the animation bug:339850589 Test manually: https://drive.google.com/file/d/1YNc3vq9Cb5BcbcPOHp8H3lhe6KmYBdLI/view?usp=sharing Flag:ACONFIG com.android.launcher3.private_space_floating_mask_view STAGING Change-Id: I7c303e6629d83408bd314886fe10113246e44dcb
This commit is contained in:
@@ -57,6 +57,7 @@ import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.recyclerview.widget.LinearSmoothScroller;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@@ -93,14 +94,17 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
private static final int TEXT_UNLOCK_OPACITY_DURATION = 300;
|
||||
private static final int TEXT_LOCK_OPACITY_DURATION = 50;
|
||||
private static final int APP_OPACITY_DURATION = 400;
|
||||
private static final int MASK_VIEW_DURATION = 200;
|
||||
private static final int APP_OPACITY_DELAY = 400;
|
||||
private static final int SETTINGS_AND_LOCK_GROUP_TRANSITION_DELAY = 400;
|
||||
private static final int SETTINGS_OPACITY_DELAY = 400;
|
||||
private static final int LOCK_TEXT_OPACITY_DELAY = 500;
|
||||
private static final int MASK_VIEW_DELAY = 400;
|
||||
private static final int NO_DELAY = 0;
|
||||
private final ActivityAllAppsContainerView<?> mAllApps;
|
||||
private final Predicate<UserHandle> mPrivateProfileMatcher;
|
||||
private final int mPsHeaderHeight;
|
||||
private final int mFloatingMaskViewCornerRadius;
|
||||
private final RecyclerView.OnScrollListener mOnIdleScrollListener =
|
||||
new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
@@ -120,6 +124,7 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
private Runnable mOnPSHeaderAdded;
|
||||
@Nullable
|
||||
private RelativeLayout mPSHeader;
|
||||
private ConstraintLayout mFloatingMaskView;
|
||||
private final String mLockedStateContentDesc;
|
||||
private final String mUnLockedStateContentDesc;
|
||||
|
||||
@@ -139,6 +144,8 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
.getString(R.string.ps_container_lock_button_content_description);
|
||||
mUnLockedStateContentDesc = mAllApps.getContext()
|
||||
.getString(R.string.ps_container_unlock_button_content_description);
|
||||
mFloatingMaskViewCornerRadius = mAllApps.getContext().getResources().getDimensionPixelSize(
|
||||
R.dimen.ps_floating_mask_corner_radius);
|
||||
}
|
||||
|
||||
/** Adds Private Space Header to the layout. */
|
||||
@@ -216,6 +223,7 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED);
|
||||
int updatedState = isEnabled ? STATE_ENABLED : STATE_DISABLED;
|
||||
setCurrentState(updatedState);
|
||||
mFloatingMaskView = null;
|
||||
if (mPSHeader != null) {
|
||||
mPSHeader.setAlpha(1);
|
||||
}
|
||||
@@ -491,12 +499,15 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
RecyclerView.LayoutManager layoutManager = allAppsRecyclerView.getLayoutManager();
|
||||
if (layoutManager != null) {
|
||||
startAnimationScroll(allAppsRecyclerView, layoutManager, smoothScroller);
|
||||
currentItem.decorationInfo = null;
|
||||
// Preserve decorator if floating mask view exists.
|
||||
if (mFloatingMaskView == null) {
|
||||
currentItem.decorationInfo = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Make the private space apps gone to "collapse".
|
||||
if (isPrivateSpaceItem(currentItem)) {
|
||||
if (mFloatingMaskView == null && isPrivateSpaceItem(currentItem)) {
|
||||
RecyclerView.ViewHolder viewHolder =
|
||||
allAppsRecyclerView.findViewHolderForAdapterPosition(i);
|
||||
if (viewHolder != null) {
|
||||
@@ -634,6 +645,7 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
setAnimationRunning(false);
|
||||
return;
|
||||
}
|
||||
attachFloatingMaskView(expand);
|
||||
ViewGroup settingsAndLockGroup = mPSHeader.findViewById(R.id.settingsAndLockGroup);
|
||||
ViewGroup lockButton = mPSHeader.findViewById(R.id.ps_lock_unlock_button);
|
||||
TextView lockText = lockButton.findViewById(R.id.lock_text);
|
||||
@@ -657,6 +669,11 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
lockText.setVisibility(expand ? VISIBLE : GONE);
|
||||
setAnimationRunning(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
detachFloatingMaskView();
|
||||
}
|
||||
});
|
||||
animatorSet.addListener(forEndCallback(() -> {
|
||||
setAnimationRunning(false);
|
||||
@@ -671,13 +688,17 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
}
|
||||
}));
|
||||
if (expand) {
|
||||
animatorSet.playTogether(animateAlphaOfIcons(true));
|
||||
animatorSet.playTogether(animateAlphaOfIcons(true),
|
||||
translateFloatingMaskView(false));
|
||||
} else {
|
||||
if (isPrivateSpaceHidden()) {
|
||||
animatorSet.playSequentially(animateAlphaOfIcons(false),
|
||||
animateCollapseAnimation(), fadeOutHeaderAlpha());
|
||||
animatorSet.playSequentially(translateFloatingMaskView(false),
|
||||
animateAlphaOfIcons(false),
|
||||
animateCollapseAnimation(),
|
||||
fadeOutHeaderAlpha());
|
||||
} else {
|
||||
animatorSet.playSequentially(animateAlphaOfIcons(false),
|
||||
animatorSet.playSequentially(translateFloatingMaskView(true),
|
||||
animateAlphaOfIcons(false),
|
||||
animateCollapseAnimation());
|
||||
}
|
||||
}
|
||||
@@ -705,6 +726,27 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
return alphaAnim;
|
||||
}
|
||||
|
||||
/** Fades out the private space container. */
|
||||
private ValueAnimator translateFloatingMaskView(boolean animateIn) {
|
||||
if (!Flags.privateSpaceFloatingMaskView() || mFloatingMaskView == null) {
|
||||
return new ValueAnimator();
|
||||
}
|
||||
// Translate base on the height amount. Translates out on expand and in on collapse.
|
||||
float floatingMaskViewHeight = getFloatingMaskViewHeight();
|
||||
float from = animateIn ? floatingMaskViewHeight : 0;
|
||||
float to = animateIn ? 0 : floatingMaskViewHeight;
|
||||
ValueAnimator alphaAnim = ObjectAnimator.ofFloat(from, to);
|
||||
alphaAnim.setDuration(MASK_VIEW_DURATION);
|
||||
alphaAnim.setStartDelay(MASK_VIEW_DELAY);
|
||||
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator valueAnimator) {
|
||||
mFloatingMaskView.setTranslationY((float) valueAnimator.getAnimatedValue());
|
||||
}
|
||||
});
|
||||
return alphaAnim;
|
||||
}
|
||||
|
||||
/** Animates the layout changes when the text of the button becomes visible/gone. */
|
||||
private void enableLayoutTransition(ViewGroup settingsAndLockGroup) {
|
||||
LayoutTransition settingsAndLockTransition = new LayoutTransition();
|
||||
@@ -771,6 +813,28 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
});
|
||||
}
|
||||
|
||||
private void attachFloatingMaskView(boolean expand) {
|
||||
if (!Flags.privateSpaceFloatingMaskView()) {
|
||||
return;
|
||||
}
|
||||
mFloatingMaskView = (FloatingMaskView) mAllApps.getLayoutInflater().inflate(
|
||||
R.layout.private_space_mask_view, mAllApps, false);
|
||||
mAllApps.addView(mFloatingMaskView);
|
||||
// Translate off the screen first if its collapsing so this header view isn't visible to
|
||||
// user when animation starts.
|
||||
if (!expand) {
|
||||
mFloatingMaskView.setTranslationY(getFloatingMaskViewHeight());
|
||||
}
|
||||
mFloatingMaskView.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
private void detachFloatingMaskView() {
|
||||
if (mFloatingMaskView != null) {
|
||||
mAllApps.removeView(mFloatingMaskView);
|
||||
}
|
||||
mFloatingMaskView = null;
|
||||
}
|
||||
|
||||
/** Starts the smooth scroll with the provided smoothScroller and add idle listener. */
|
||||
private void startAnimationScroll(AllAppsRecyclerView allAppsRecyclerView,
|
||||
RecyclerView.LayoutManager layoutManager, RecyclerView.SmoothScroller smoothScroller) {
|
||||
@@ -780,6 +844,10 @@ public class PrivateProfileManager extends UserProfileManager {
|
||||
allAppsRecyclerView.addOnScrollListener(mOnIdleScrollListener);
|
||||
}
|
||||
|
||||
private float getFloatingMaskViewHeight() {
|
||||
return mFloatingMaskViewCornerRadius + getMainRecyclerView().getPaddingBottom();
|
||||
}
|
||||
|
||||
AllAppsRecyclerView getMainRecyclerView() {
|
||||
return mAllApps.mAH.get(ActivityAllAppsContainerView.AdapterHolder.MAIN).mRecyclerView;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user