Merge "Update bubble bar stash and unstash animation" into main

This commit is contained in:
Ats Jenk
2024-08-30 19:30:14 +00:00
committed by Android (Google) Code Review
9 changed files with 248 additions and 143 deletions
@@ -21,6 +21,7 @@ import static android.view.View.VISIBLE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Rect;
@@ -28,6 +29,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewOutlineProvider;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.anim.RevealOutlineAnimation;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
@@ -49,23 +51,29 @@ public class BubbleStashedHandleViewController {
private final TaskbarActivityContext mActivity;
private final StashedHandleView mStashedHandleView;
private final MultiValueAlpha mStashedHandleAlpha;
private float mTranslationForSwipeY;
private float mTranslationForStashY;
// Initialized in init.
private BubbleBarViewController mBarViewController;
private BubbleStashController mBubbleStashController;
private RegionSamplingHelper mRegionSamplingHelper;
private int mBarSize;
private int mStashedTaskbarHeight;
// Height of the area for the stash handle. Handle will be drawn in the center of this.
// This is also the area where touch is handled on the handle.
private int mStashedBubbleBarHeight;
private int mStashedHandleWidth;
private int mStashedHandleHeight;
// The bounds we want to clip to in the settled state when showing the stashed handle.
// The bounds of the stashed handle in settled state.
private final Rect mStashedHandleBounds = new Rect();
private float mStashedHandleRadius;
// When the reveal animation is cancelled, we can assume it's about to create a new animation,
// which should start off at the same point the cancelled one left off.
private float mStartProgressForNextRevealAnim;
private boolean mWasLastRevealAnimReversed;
// Use a nullable boolean to handle initial case where the last animation direction is not known
@Nullable
private Boolean mWasLastRevealAnimReversed = null;
// XXX: if there are more of these maybe do state flags instead
private boolean mHiddenForSysui;
@@ -77,6 +85,7 @@ public class BubbleStashedHandleViewController {
mActivity = activity;
mStashedHandleView = stashedHandleView;
mStashedHandleAlpha = new MultiValueAlpha(mStashedHandleView, 1);
mStashedHandleAlpha.setUpdateVisibility(true);
}
/** Initialize controller. */
@@ -84,26 +93,31 @@ public class BubbleStashedHandleViewController {
mBarViewController = bubbleControllers.bubbleBarViewController;
mBubbleStashController = bubbleControllers.bubbleStashController;
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
Resources resources = mActivity.getResources();
mStashedHandleHeight = resources.getDimensionPixelSize(
R.dimen.bubblebar_stashed_handle_height);
mStashedHandleWidth = resources.getDimensionPixelSize(
R.dimen.bubblebar_stashed_handle_width);
mBarSize = resources.getDimensionPixelSize(R.dimen.bubblebar_size);
final int bottomMargin = resources.getDimensionPixelSize(
R.dimen.transient_taskbar_bottom_margin);
mStashedHandleView.getLayoutParams().height = mBarSize + bottomMargin;
int barSize = resources.getDimensionPixelSize(R.dimen.bubblebar_size);
// Use the max translation for bubble bar whether it is on the home screen or in app.
// Use values directly from device profile to avoid referencing other bubble controllers
// during init flow.
int maxTy = Math.max(deviceProfile.hotseatBarBottomSpacePx,
deviceProfile.taskbarBottomMargin);
// Adjust handle view size to accommodate the handle morphing into the bubble bar
mStashedHandleView.getLayoutParams().height = barSize + maxTy;
mStashedHandleAlpha.get(0).setValue(0);
mStashedTaskbarHeight = resources.getDimensionPixelSize(
mStashedBubbleBarHeight = resources.getDimensionPixelSize(
R.dimen.bubblebar_stashed_size);
mStashedHandleView.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
float stashedHandleRadius = view.getHeight() / 2f;
outline.setRoundRect(mStashedHandleBounds, stashedHandleRadius);
mStashedHandleRadius = view.getHeight() / 2f;
outline.setRoundRect(mStashedHandleBounds, mStashedHandleRadius);
}
});
@@ -132,28 +146,25 @@ public class BubbleStashedHandleViewController {
private void updateBounds(BubbleBarLocation bubbleBarLocation) {
// As more bubbles get added, the icon bounds become larger. To ensure a consistent
// handle bar position, we pin it to the edge of the screen.
final int stashedCenterY = mStashedHandleView.getHeight() - mStashedTaskbarHeight / 2;
final int stashedCenterY = mStashedHandleView.getHeight() - mStashedBubbleBarHeight / 2;
final int stashedCenterX;
if (bubbleBarLocation.isOnLeft(mStashedHandleView.isLayoutRtl())) {
final int left = mBarViewController.getHorizontalMargin();
mStashedHandleBounds.set(
left,
stashedCenterY - mStashedHandleHeight / 2,
left + mStashedHandleWidth,
stashedCenterY + mStashedHandleHeight / 2);
mStashedHandleView.setPivotX(0);
stashedCenterX = left + mStashedHandleWidth / 2;
} else {
final int right =
mActivity.getDeviceProfile().widthPx - mBarViewController.getHorizontalMargin();
mStashedHandleBounds.set(
right - mStashedHandleWidth,
stashedCenterY - mStashedHandleHeight / 2,
right,
stashedCenterY + mStashedHandleHeight / 2);
mStashedHandleView.setPivotX(mStashedHandleView.getWidth());
mStashedHandleView.getRight() - mBarViewController.getHorizontalMargin();
stashedCenterX = right - mStashedHandleWidth / 2;
}
mStashedHandleBounds.set(
stashedCenterX - mStashedHandleWidth / 2,
stashedCenterY - mStashedHandleHeight / 2,
stashedCenterX + mStashedHandleWidth / 2,
stashedCenterY + mStashedHandleHeight / 2
);
mStashedHandleView.updateSampledRegion(mStashedHandleBounds);
mStashedHandleView.setPivotY(mStashedHandleView.getHeight() - mStashedTaskbarHeight / 2f);
mStashedHandleView.setPivotX(stashedCenterX);
mStashedHandleView.setPivotY(stashedCenterY);
}
public void onDestroy() {
@@ -168,13 +179,6 @@ public class BubbleStashedHandleViewController {
return mStashedHandleHeight;
}
/**
* Returns the height when the bubble bar is unstashed (so the height of the bubble bar).
*/
public int getUnstashedHeight() {
return mBarSize;
}
/**
* Called when system ui state changes. Bubbles don't show when the device is locked.
*/
@@ -242,7 +246,20 @@ public class BubbleStashedHandleViewController {
* Sets the translation of the stashed handle during the swipe up gesture.
*/
public void setTranslationYForSwipe(float transY) {
mStashedHandleView.setTranslationY(transY);
mTranslationForSwipeY = transY;
updateTranslationY();
}
/**
* Sets the translation of the stashed handle during the spring on stash animation.
*/
public void setTranslationYForStash(float transY) {
mTranslationForStashY = transY;
updateTranslationY();
}
private void updateTranslationY() {
mStashedHandleView.setTranslationY(mTranslationForSwipeY + mTranslationForStashY);
}
/** Returns the translation of the stashed handle. */
@@ -263,18 +280,17 @@ public class BubbleStashedHandleViewController {
* the size of where the bubble bar icons will be.
*/
public Animator createRevealAnimToIsStashed(boolean isStashed) {
Rect bubbleBarBounds = new Rect(mBarViewController.getBubbleBarBounds());
Rect bubbleBarBounds = getLocalBubbleBarBounds();
// Account for the full visual height of the bubble bar
int heightDiff = (mBarSize - bubbleBarBounds.height()) / 2;
bubbleBarBounds.top -= heightDiff;
bubbleBarBounds.bottom += heightDiff;
float stashedHandleRadius = mStashedHandleView.getHeight() / 2f;
float bubbleBarRadius = bubbleBarBounds.height() / 2f;
final RevealOutlineAnimation handleRevealProvider = new RoundedRectRevealOutlineProvider(
stashedHandleRadius, stashedHandleRadius, bubbleBarBounds, mStashedHandleBounds);
bubbleBarRadius, mStashedHandleRadius, bubbleBarBounds, mStashedHandleBounds);
boolean isReversed = !isStashed;
boolean changingDirection = mWasLastRevealAnimReversed != isReversed;
// We are only changing direction when mWasLastRevealAnimReversed is set at least once
boolean changingDirection =
mWasLastRevealAnimReversed != null && mWasLastRevealAnimReversed != isReversed;
mWasLastRevealAnimReversed = isReversed;
if (changingDirection) {
mStartProgressForNextRevealAnim = 1f - mStartProgressForNextRevealAnim;
@@ -291,6 +307,21 @@ public class BubbleStashedHandleViewController {
return revealAnim;
}
/**
* Get bounds for the bubble bar in the space of the handle view
*/
private Rect getLocalBubbleBarBounds() {
// Position the bubble bar bounds to the space of handle view
Rect bubbleBarBounds = new Rect(mBarViewController.getBubbleBarBounds());
// Start by moving bubble bar bounds to the bottom of handle view
int height = bubbleBarBounds.height();
bubbleBarBounds.bottom = mStashedHandleView.getHeight();
bubbleBarBounds.top = bubbleBarBounds.bottom - height;
// Then apply translation that is applied to the bubble bar
bubbleBarBounds.offset(0, (int) mBubbleStashController.getBubbleBarTranslationY());
return bubbleBarBounds;
}
/** Checks that the stash handle is visible and that the motion event is within bounds. */
public boolean isEventOverHandle(MotionEvent ev) {
if (mStashedHandleView.getVisibility() != VISIBLE) {
@@ -299,7 +330,7 @@ public class BubbleStashedHandleViewController {
// the bounds of the handle only include the visible part, so we check that the Y coordinate
// is anywhere within the stashed height of bubble bar (same as taskbar stashed height).
final int top = mActivity.getDeviceProfile().heightPx - mStashedTaskbarHeight;
final int top = mActivity.getDeviceProfile().heightPx - mStashedBubbleBarHeight;
final float x = ev.getRawX();
return ev.getRawY() >= top && x >= mStashedHandleBounds.left
&& x <= mStashedHandleBounds.right;