mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-04 18:06:48 +00:00
Fix flickering issues with divider during split animation
This CL makes changes to the "split divider placeholder view", which was intended to cover up the backdrop a little during the split confirm animation. The placeholder view is now larger (fullscreen) and fades in with the animation movement, so there is no longer a period of time when it looks like an awkward rectangle. New timings and interpolators confirmed with UX. Also renamed some variables and added comments for clarity. Fixes: 344573331 Test: Manually verified that the visual bug no longer happens on large and small screen, and from desktop and Overview. Flag: EXEMPT bugfix Change-Id: I3b37f2b0478035d7a3181ae7c23962fe75a13b2c
This commit is contained in:
@@ -27,6 +27,8 @@ public class PhoneSplitToConfirmTimings
|
||||
public int getPlaceholderIconFadeInEnd() { return 133; }
|
||||
public int getStagedRectSlideStart() { return 0; }
|
||||
public int getStagedRectSlideEnd() { return 333; }
|
||||
public int getBackingScrimFadeInStart() { return 0; }
|
||||
public int getBackingScrimFadeInEnd() { return 266; }
|
||||
|
||||
public int getDuration() { return PHONE_CONFIRM_DURATION; }
|
||||
}
|
||||
|
||||
@@ -281,64 +281,45 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a view to fade in at .4 animation progress and adds it to the provided
|
||||
* [pendingAnimation]. Assumes that animation will be the final split placeholder launch anim.
|
||||
*
|
||||
* [secondPlaceholderEndingBounds] refers to the second placeholder view that gets added on
|
||||
* screen, not the logical second app. For landscape it's the left app and for portrait the top
|
||||
* one.
|
||||
* Creates and returns a fullscreen scrim to fade in behind the split confirm animation, and
|
||||
* adds it to the provided [pendingAnimation].
|
||||
*/
|
||||
fun addDividerPlaceholderViewToAnim(
|
||||
fun addScrimBehindAnim(
|
||||
pendingAnimation: PendingAnimation,
|
||||
container: RecentsViewContainer,
|
||||
secondPlaceholderEndingBounds: Rect,
|
||||
context: Context
|
||||
): View {
|
||||
val mSplitDividerPlaceholderView = View(context)
|
||||
val scrim = View(context)
|
||||
val recentsView = container.getOverviewPanel<RecentsView<*, *>>()
|
||||
val dp: com.android.launcher3.DeviceProfile = container.getDeviceProfile()
|
||||
val dp: DeviceProfile = container.getDeviceProfile()
|
||||
// Add it before/under the most recently added first floating taskView
|
||||
val firstAddedSplitViewIndex: Int =
|
||||
container
|
||||
.getDragLayer()
|
||||
.indexOfChild(recentsView.splitSelectController.firstFloatingTaskView)
|
||||
container.getDragLayer().addView(mSplitDividerPlaceholderView, firstAddedSplitViewIndex)
|
||||
val lp = mSplitDividerPlaceholderView.layoutParams as InsettableFrameLayout.LayoutParams
|
||||
container.getDragLayer().addView(scrim, firstAddedSplitViewIndex)
|
||||
// Make the scrim fullscreen
|
||||
val lp = scrim.layoutParams as InsettableFrameLayout.LayoutParams
|
||||
lp.topMargin = 0
|
||||
lp.height = dp.heightPx
|
||||
lp.width = dp.widthPx
|
||||
|
||||
if (dp.isLeftRightSplit) {
|
||||
lp.height = secondPlaceholderEndingBounds.height()
|
||||
lp.width =
|
||||
container
|
||||
.asContext()
|
||||
.resources
|
||||
.getDimensionPixelSize(R.dimen.split_divider_handle_region_height)
|
||||
mSplitDividerPlaceholderView.translationX =
|
||||
secondPlaceholderEndingBounds.right - lp.width / 2f
|
||||
mSplitDividerPlaceholderView.translationY = 0f
|
||||
} else {
|
||||
lp.height =
|
||||
container
|
||||
.asContext()
|
||||
.resources
|
||||
.getDimensionPixelSize(R.dimen.split_divider_handle_region_height)
|
||||
lp.width = secondPlaceholderEndingBounds.width()
|
||||
mSplitDividerPlaceholderView.translationY =
|
||||
secondPlaceholderEndingBounds.top - lp.height / 2f
|
||||
mSplitDividerPlaceholderView.translationX = 0f
|
||||
}
|
||||
|
||||
mSplitDividerPlaceholderView.alpha = 0f
|
||||
mSplitDividerPlaceholderView.setBackgroundColor(
|
||||
scrim.alpha = 0f
|
||||
scrim.setBackgroundColor(
|
||||
container.asContext().resources.getColor(R.color.taskbar_background_dark)
|
||||
)
|
||||
val timings = AnimUtils.getDeviceSplitToConfirmTimings(dp.isTablet)
|
||||
val timings = AnimUtils.getDeviceSplitToConfirmTimings(dp.isTablet) as SplitToConfirmTimings
|
||||
pendingAnimation.setViewAlpha(
|
||||
mSplitDividerPlaceholderView,
|
||||
scrim,
|
||||
1f,
|
||||
Interpolators.clampToProgress(timings.stagedRectScaleXInterpolator, 0.4f, 1f)
|
||||
Interpolators.clampToProgress(
|
||||
timings.backingScrimFadeInterpolator,
|
||||
timings.backingScrimFadeInStartOffset,
|
||||
timings.backingScrimFadeInEndOffset
|
||||
)
|
||||
)
|
||||
return mSplitDividerPlaceholderView
|
||||
|
||||
return scrim
|
||||
}
|
||||
|
||||
/** Does not play any animation if user is not currently in split selection state. */
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import static com.android.app.animation.Interpolators.EMPHASIZED;
|
||||
import static com.android.app.animation.Interpolators.LINEAR;
|
||||
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
@@ -31,6 +32,8 @@ abstract class SplitToConfirmTimings implements SplitAnimationTimings {
|
||||
abstract public int getPlaceholderIconFadeInEnd();
|
||||
abstract public int getStagedRectSlideStart();
|
||||
abstract public int getStagedRectSlideEnd();
|
||||
abstract public int getBackingScrimFadeInStart();
|
||||
abstract public int getBackingScrimFadeInEnd();
|
||||
|
||||
// Common timings
|
||||
public int getInstructionsFadeStart() { return 0; }
|
||||
@@ -39,6 +42,7 @@ abstract class SplitToConfirmTimings implements SplitAnimationTimings {
|
||||
public Interpolator getStagedRectYInterpolator() { return EMPHASIZED; }
|
||||
public Interpolator getStagedRectScaleXInterpolator() { return EMPHASIZED; }
|
||||
public Interpolator getStagedRectScaleYInterpolator() { return EMPHASIZED; }
|
||||
public Interpolator getBackingScrimFadeInterpolator() { return LINEAR; }
|
||||
|
||||
abstract public int getDuration();
|
||||
|
||||
@@ -48,4 +52,10 @@ abstract class SplitToConfirmTimings implements SplitAnimationTimings {
|
||||
public float getInstructionsFadeEndOffset() {
|
||||
return (float) getInstructionsFadeEnd() / getDuration();
|
||||
}
|
||||
public float getBackingScrimFadeInStartOffset() {
|
||||
return (float) getBackingScrimFadeInStart() / getDuration();
|
||||
}
|
||||
public float getBackingScrimFadeInEndOffset() {
|
||||
return (float) getBackingScrimFadeInEnd() / getDuration();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,9 +163,8 @@ public class SplitToWorkspaceController {
|
||||
new RectF(firstTaskStartingBounds), firstTaskEndingBounds,
|
||||
false /* fadeWithThumbnail */, true /* isStagedTask */);
|
||||
|
||||
View mSplitDividerPlaceholderView = recentsView.getSplitSelectController()
|
||||
.getSplitAnimationController().addDividerPlaceholderViewToAnim(pendingAnimation,
|
||||
mLauncher, secondTaskEndingBounds, view.getContext());
|
||||
View backingScrim = recentsView.getSplitSelectController().getSplitAnimationController()
|
||||
.addScrimBehindAnim(pendingAnimation, mLauncher, view.getContext());
|
||||
|
||||
FloatingTaskView secondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mLauncher,
|
||||
view, bitmap, icon, secondTaskStartingBounds);
|
||||
@@ -197,7 +196,7 @@ public class SplitToWorkspaceController {
|
||||
private void cleanUp() {
|
||||
mLauncher.getDragLayer().removeView(firstFloatingTaskView);
|
||||
mLauncher.getDragLayer().removeView(secondFloatingTaskView);
|
||||
mLauncher.getDragLayer().removeView(mSplitDividerPlaceholderView);
|
||||
mLauncher.getDragLayer().removeView(backingScrim);
|
||||
mController.getSplitAnimationController().removeSplitInstructionsView(mLauncher);
|
||||
mController.resetState();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ public class TabletSplitToConfirmTimings
|
||||
public int getPlaceholderIconFadeInEnd() { return 250; }
|
||||
public int getStagedRectSlideStart() { return 0; }
|
||||
public int getStagedRectSlideEnd() { return 500; }
|
||||
public int getBackingScrimFadeInStart() { return 0; }
|
||||
public int getBackingScrimFadeInEnd() { return 400; }
|
||||
|
||||
public int getDuration() { return TABLET_CONFIRM_DURATION; }
|
||||
}
|
||||
|
||||
@@ -738,7 +738,11 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
private int mSplitHiddenTaskViewIndex = -1;
|
||||
@Nullable
|
||||
private FloatingTaskView mSecondFloatingTaskView;
|
||||
private View mSplitDividerPlaceholderView;
|
||||
/**
|
||||
* A fullscreen scrim that goes behind the splitscreen animation to hide color conflicts and
|
||||
* possible flickers. Removed after tasks + divider finish animating in.
|
||||
*/
|
||||
private View mSplitScrim;
|
||||
|
||||
/**
|
||||
* The task to be removed and immediately re-added. Should not be added to task pool.
|
||||
@@ -4926,9 +4930,8 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
mSplitSelectStateController.getActiveSplitStagePosition(), firstTaskEndingBounds,
|
||||
secondTaskEndingBounds);
|
||||
|
||||
mSplitDividerPlaceholderView = mSplitSelectStateController
|
||||
.getSplitAnimationController().addDividerPlaceholderViewToAnim(pendingAnimation,
|
||||
mContainer, secondTaskEndingBounds, getContext());
|
||||
mSplitScrim = mSplitSelectStateController.getSplitAnimationController()
|
||||
.addScrimBehindAnim(pendingAnimation, mContainer, getContext());
|
||||
FloatingTaskView firstFloatingTaskView =
|
||||
mSplitSelectStateController.getFirstFloatingTaskView();
|
||||
firstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
|
||||
@@ -4983,7 +4986,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
safeRemoveDragLayerView(mSplitSelectStateController.getFirstFloatingTaskView());
|
||||
safeRemoveDragLayerView(mSecondFloatingTaskView);
|
||||
safeRemoveDragLayerView(mSplitSelectStateController.getSplitInstructionsView());
|
||||
safeRemoveDragLayerView(mSplitDividerPlaceholderView);
|
||||
safeRemoveDragLayerView(mSplitScrim);
|
||||
mSecondFloatingTaskView = null;
|
||||
mSplitSelectSource = null;
|
||||
mSplitSelectStateController.getSplitAnimationController()
|
||||
|
||||
Reference in New Issue
Block a user