mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 03:08:19 +00:00
Merge "Add additional fake task views on overview gesture completion."
This commit is contained in:
committed by
Android (Google) Code Review
commit
618ba37e04
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/gesture_tutorial_fake_previous_task_view_color" />
|
||||
</shape>
|
||||
@@ -30,6 +30,14 @@
|
||||
android:layout_height="20dp"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<View
|
||||
android:id="@+id/gesture_tutorial_fake_previous_task_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleX="0.98"
|
||||
android:scaleY="0.98"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<View
|
||||
android:id="@+id/gesture_tutorial_fake_task_view"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -56,7 +56,7 @@ import com.android.systemui.shared.system.QuickStepContract;
|
||||
|
||||
/** Utility class to handle Home and Assistant gestures. */
|
||||
public class NavBarGestureHandler implements OnTouchListener,
|
||||
TriggerSwipeUpTouchTracker.OnSwipeUpListener {
|
||||
TriggerSwipeUpTouchTracker.OnSwipeUpListener, MotionPauseDetector.OnMotionPauseListener {
|
||||
|
||||
private static final String LOG_TAG = "NavBarGestureHandler";
|
||||
private static final long RETRACT_GESTURE_ANIMATION_DURATION_MS = 300;
|
||||
@@ -181,7 +181,7 @@ public class NavBarGestureHandler implements OnTouchListener,
|
||||
mLaunchedAssistant = false;
|
||||
mSwipeUpTouchTracker.init();
|
||||
mMotionPauseDetector.clear();
|
||||
mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseDetected);
|
||||
mMotionPauseDetector.setOnMotionPauseListener(this);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
mLastPos.set(event.getX(), event.getY());
|
||||
@@ -256,7 +256,13 @@ public class NavBarGestureHandler implements OnTouchListener,
|
||||
|| event.getY() >= mDisplaySize.y - mBottomGestureHeight;
|
||||
}
|
||||
|
||||
protected void onMotionPauseDetected() {
|
||||
@Override
|
||||
public void onMotionPauseChanged(boolean isPaused) {
|
||||
mGestureCallback.onMotionPaused(isPaused);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMotionPauseDetected() {
|
||||
VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC);
|
||||
}
|
||||
|
||||
@@ -311,6 +317,9 @@ public class NavBarGestureHandler implements OnTouchListener,
|
||||
/** Called whenever any touch is completed. */
|
||||
void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity);
|
||||
|
||||
/** Called when a motion stops or resumes */
|
||||
default void onMotionPaused(boolean isPaused) {}
|
||||
|
||||
/** Indicates how far a touch originating in the nav bar has moved from the nav bar. */
|
||||
default void setNavBarGestureProgress(@Nullable Float displacement) {}
|
||||
|
||||
|
||||
@@ -61,16 +61,21 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.R)
|
||||
abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
private final ViewSwipeUpAnimation mViewSwipeUpAnimation;
|
||||
|
||||
private static final int FAKE_PREVIOUS_TASK_MARGIN = Utilities.dpToPx(12);
|
||||
|
||||
private final ViewSwipeUpAnimation mTaskViewSwipeUpAnimation;
|
||||
private float mFakeTaskViewRadius;
|
||||
private Rect mFakeTaskViewRect = new Rect();
|
||||
private RunningWindowAnim mRunningWindowAnim;
|
||||
private boolean mShowTasks = false;
|
||||
private boolean mShowPreviousTasks = false;
|
||||
|
||||
SwipeUpGestureTutorialController(TutorialFragment tutorialFragment, TutorialType tutorialType) {
|
||||
super(tutorialFragment, tutorialType);
|
||||
RecentsAnimationDeviceState deviceState = new RecentsAnimationDeviceState(mContext);
|
||||
OverviewComponentObserver observer = new OverviewComponentObserver(mContext, deviceState);
|
||||
mViewSwipeUpAnimation = new ViewSwipeUpAnimation(mContext, deviceState,
|
||||
mTaskViewSwipeUpAnimation = new ViewSwipeUpAnimation(mContext, deviceState,
|
||||
new GestureState(observer, -1));
|
||||
observer.onDestroy();
|
||||
deviceState.destroy();
|
||||
@@ -83,16 +88,22 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
.getWindowInsets()
|
||||
.getInsets(WindowInsets.Type.systemBars());
|
||||
dp.updateInsets(new Rect(insets.left, insets.top, insets.right, insets.bottom));
|
||||
mViewSwipeUpAnimation.initDp(dp);
|
||||
mTaskViewSwipeUpAnimation.initDp(dp);
|
||||
|
||||
mFakeTaskViewRadius = QuickStepContract.getWindowCornerRadius(mContext.getResources());
|
||||
mFakeTaskView.setClipToOutline(true);
|
||||
mFakeTaskView.setOutlineProvider(new ViewOutlineProvider() {
|
||||
|
||||
ViewOutlineProvider outlineProvider = new ViewOutlineProvider() {
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline) {
|
||||
outline.setRoundRect(mFakeTaskViewRect, mFakeTaskViewRadius);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
mFakeTaskView.setClipToOutline(true);
|
||||
mFakeTaskView.setOutlineProvider(outlineProvider);
|
||||
|
||||
mFakePreviousTaskView.setClipToOutline(true);
|
||||
mFakePreviousTaskView.setOutlineProvider(outlineProvider);
|
||||
}
|
||||
|
||||
private void cancelRunningAnimation() {
|
||||
@@ -114,16 +125,22 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
mFakeIconView.setVisibility(View.INVISIBLE);
|
||||
mFakeTaskView.setVisibility(View.INVISIBLE);
|
||||
mFakeTaskView.setAlpha(1);
|
||||
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
|
||||
mFakePreviousTaskView.setAlpha(1);
|
||||
mShowTasks = false;
|
||||
mShowPreviousTasks = false;
|
||||
mRunningWindowAnim = null;
|
||||
}
|
||||
};
|
||||
if (toOverviewFirst) {
|
||||
anim.setFloat(mViewSwipeUpAnimation.getCurrentShift(), AnimatedFloat.VALUE, 1, ACCEL);
|
||||
anim.setFloat(mTaskViewSwipeUpAnimation
|
||||
.getCurrentShift(), AnimatedFloat.VALUE, 1, ACCEL);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation, boolean isReverse) {
|
||||
PendingAnimation fadeAnim = new PendingAnimation(300);
|
||||
fadeAnim.setViewAlpha(mFakeTaskView, 0, ACCEL);
|
||||
fadeAnim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL);
|
||||
fadeAnim.addListener(resetTaskView);
|
||||
AnimatorSet animset = fadeAnim.buildAnim();
|
||||
animset.setStartDelay(100);
|
||||
@@ -133,6 +150,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
});
|
||||
} else {
|
||||
anim.setViewAlpha(mFakeTaskView, 0, ACCEL);
|
||||
anim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL);
|
||||
anim.setViewAlpha(mFakeIconView, 0, ACCEL);
|
||||
anim.addListener(resetTaskView);
|
||||
}
|
||||
@@ -148,8 +166,10 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
hideFeedback();
|
||||
hideHandCoachingAnimation();
|
||||
cancelRunningAnimation();
|
||||
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
|
||||
mShowPreviousTasks = false;
|
||||
RectFSpringAnim rectAnim =
|
||||
mViewSwipeUpAnimation.handleSwipeUpToHome(finalVelocity);
|
||||
mTaskViewSwipeUpAnimation.handleSwipeUpToHome(finalVelocity);
|
||||
// After home animation finishes, fade out and run onEndRunnable.
|
||||
rectAnim.addAnimatorListener(AnimationSuccessListener.forRunnable(
|
||||
() -> fadeOutFakeTaskView(false, onEndRunnable)));
|
||||
@@ -161,11 +181,31 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
if (displacement == null || mTutorialType == HOME_NAVIGATION_COMPLETE
|
||||
|| mTutorialType == OVERVIEW_NAVIGATION_COMPLETE) {
|
||||
mFakeTaskView.setVisibility(View.INVISIBLE);
|
||||
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
mShowTasks = true;
|
||||
mFakeTaskView.setVisibility(View.VISIBLE);
|
||||
if (mRunningWindowAnim == null) {
|
||||
mViewSwipeUpAnimation.updateDisplacement(displacement);
|
||||
if (mShowPreviousTasks) {
|
||||
mFakePreviousTaskView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (mRunningWindowAnim == null) {
|
||||
mTaskViewSwipeUpAnimation.updateDisplacement(displacement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMotionPaused(boolean unused) {
|
||||
if (mShowTasks) {
|
||||
if (!mShowPreviousTasks) {
|
||||
mFakePreviousTaskView.setTranslationX(
|
||||
-(2 * mFakePreviousTaskView.getWidth() + FAKE_PREVIOUS_TASK_MARGIN));
|
||||
mFakePreviousTaskView.animate()
|
||||
.setDuration(300)
|
||||
.translationX(-(mFakePreviousTaskView.getWidth() + FAKE_PREVIOUS_TASK_MARGIN))
|
||||
.start();
|
||||
}
|
||||
mShowPreviousTasks = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,6 +272,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
false /* isVerticalBarLayout */);
|
||||
mFakeIconView.setAlpha(1);
|
||||
mFakeTaskView.setAlpha(getWindowAlpha(progress));
|
||||
mFakePreviousTaskView.setAlpha(getWindowAlpha(progress));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -258,9 +299,11 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
public void applySurfaceParams(SurfaceParams[] params) {
|
||||
SurfaceParams p = params[0];
|
||||
mFakeTaskView.setAnimationMatrix(p.matrix);
|
||||
mFakePreviousTaskView.setAnimationMatrix(p.matrix);
|
||||
mFakeTaskViewRect.set(p.windowCrop);
|
||||
mFakeTaskViewRadius = p.cornerRadius;
|
||||
mFakeTaskView.invalidateOutline();
|
||||
mFakePreviousTaskView.invalidateOutline();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
final View mLauncherView;
|
||||
final ClipIconView mFakeIconView;
|
||||
final View mFakeTaskView;
|
||||
final View mFakePreviousTaskView;
|
||||
final View mRippleView;
|
||||
final RippleDrawable mRippleDrawable;
|
||||
@Nullable final TutorialHandAnimation mHandCoachingAnimation;
|
||||
@@ -74,6 +75,8 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
mLauncherView = getMockLauncherView();
|
||||
mFakeIconView = rootView.findViewById(R.id.gesture_tutorial_fake_icon_view);
|
||||
mFakeTaskView = rootView.findViewById(R.id.gesture_tutorial_fake_task_view);
|
||||
mFakePreviousTaskView =
|
||||
rootView.findViewById(R.id.gesture_tutorial_fake_previous_task_view);
|
||||
mRippleView = rootView.findViewById(R.id.gesture_tutorial_ripple_view);
|
||||
mRippleDrawable = (RippleDrawable) mRippleView.getBackground();
|
||||
mHandCoachingAnimation = tutorialFragment.getHandAnimation();
|
||||
@@ -93,6 +96,8 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
if (mContext != null) {
|
||||
rootView.setBackground(mContext.getDrawable(getMockWallpaperResId()));
|
||||
mFakeTaskView.setBackground(mContext.getDrawable(getMockAppTaskThumbnailResId()));
|
||||
mFakePreviousTaskView.setBackground(
|
||||
mContext.getDrawable(getMockPreviousAppTaskThumbnailResId()));
|
||||
mFakeIconView.setBackground(mContext.getDrawable(getMockAppIconResId()));
|
||||
}
|
||||
}
|
||||
@@ -126,6 +131,11 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
return R.drawable.default_sandbox_app_task_thumbnail;
|
||||
}
|
||||
|
||||
@DrawableRes
|
||||
protected int getMockPreviousAppTaskThumbnailResId() {
|
||||
return R.drawable.default_sandbox_app_previous_task_thumbnail;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public View getMockLauncherView() {
|
||||
InvariantDeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext);
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
<color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
|
||||
<color name="gesture_tutorial_fake_task_view_color">#6DA1FF</color> <!-- Light Blue -->
|
||||
<color name="gesture_tutorial_fake_previous_task_view_color">#9CCC65</color> <!-- Light Green -->
|
||||
<color name="gesture_tutorial_action_button_label_color">#FFFFFFFF</color>
|
||||
<color name="gesture_tutorial_primary_color">#1A73E8</color> <!-- Blue -->
|
||||
</resources>
|
||||
|
||||
@@ -404,6 +404,11 @@ public final class Utilities {
|
||||
return (size / densityRatio);
|
||||
}
|
||||
|
||||
/** Converts a dp value to pixels for the current device. */
|
||||
public static int dpToPx(float dp) {
|
||||
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
|
||||
}
|
||||
|
||||
public static int pxFromSp(float size, DisplayMetrics metrics) {
|
||||
return (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
|
||||
size, metrics));
|
||||
|
||||
Reference in New Issue
Block a user