Merge "Update gesture nav edu motion and colors" into udc-dev

This commit is contained in:
Schneider Victor-tulias
2023-05-26 16:12:06 +00:00
committed by Android (Google) Code Review
12 changed files with 113 additions and 211 deletions
@@ -157,6 +157,7 @@
android:layout_marginVertical="16dp" android:layout_marginVertical="16dp"
android:text="@string/gesture_tutorial_action_button_label" android:text="@string/gesture_tutorial_action_button_label"
android:background="@drawable/gesture_tutorial_action_button_background" android:background="@drawable/gesture_tutorial_action_button_background"
android:backgroundTint="?androidprv:attr/materialColorPrimary"
android:stateListAnimator="@null" android:stateListAnimator="@null"
app:layout_constraintTop_toBottomOf="@id/guideline" app:layout_constraintTop_toBottomOf="@id/guideline"
@@ -175,6 +175,7 @@
android:paddingEnd="26dp" android:paddingEnd="26dp"
android:text="@string/gesture_tutorial_action_button_label" android:text="@string/gesture_tutorial_action_button_label"
android:background="@drawable/gesture_tutorial_action_button_background" android:background="@drawable/gesture_tutorial_action_button_background"
android:backgroundTint="?android:attr/colorAccent"
android:stateListAnimator="@null" android:stateListAnimator="@null"
android:visibility="invisible" android:visibility="invisible"
@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2023 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.
-->
<View
xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="@style/GestureTutorialActivity"
android:id="@+id/overview_gesture_tutorial_shape"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:background="?attr/onSurfaceOverview" />
@@ -156,6 +156,7 @@
android:layout_marginVertical="16dp" android:layout_marginVertical="16dp"
android:text="@string/gesture_tutorial_action_button_label" android:text="@string/gesture_tutorial_action_button_label"
android:background="@drawable/gesture_tutorial_action_button_background" android:background="@drawable/gesture_tutorial_action_button_background"
android:backgroundTint="?androidprv:attr/materialColorPrimary"
android:stateListAnimator="@null" android:stateListAnimator="@null"
app:layout_constraintTop_toBottomOf="@id/guideline" app:layout_constraintTop_toBottomOf="@id/guideline"
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2023 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.
-->
<View
xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="@style/GestureTutorialActivity"
android:id="@+id/swipe_up_gesture_tutorial_shape"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/surfaceHome" />
@@ -15,10 +15,6 @@
*/ */
package com.android.quickstep.interaction; package com.android.quickstep.interaction;
import static com.android.launcher3.QuickstepTransitionManager.ANIMATION_NAV_FADE_OUT_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.NAV_FADE_OUT_INTERPOLATOR;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL; import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
import android.animation.Animator; import android.animation.Animator;
@@ -28,30 +24,19 @@ import android.animation.ObjectAnimator;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.annotation.ColorInt; import android.annotation.ColorInt;
import android.content.Context; import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Outline; import android.graphics.Outline;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.RoundedCorner;
import android.view.View; import android.view.View;
import android.view.ViewOutlineProvider; import android.view.ViewOutlineProvider;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ViewAnimator;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintLayout;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.Interpolators;
import com.android.quickstep.util.MultiValueUpdateListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
/** /**
* Helper View for the gesture tutorial mock previous app task view. * Helper View for the gesture tutorial mock previous app task view.
@@ -61,8 +46,6 @@ import java.util.Arrays;
*/ */
public class AnimatedTaskView extends ConstraintLayout { public class AnimatedTaskView extends ConstraintLayout {
private static final long ANIMATE_TO_FULL_SCREEN_DURATION = 300;
private View mFullTaskView; private View mFullTaskView;
private View mTopTaskView; private View mTopTaskView;
private View mBottomTaskView; private View mBottomTaskView;
@@ -72,17 +55,16 @@ public class AnimatedTaskView extends ConstraintLayout {
private float mTaskViewAnimatedRadius; private float mTaskViewAnimatedRadius;
public AnimatedTaskView(@NonNull Context context) { public AnimatedTaskView(@NonNull Context context) {
super(context); this(context, null);
} }
public AnimatedTaskView(@NonNull Context context, public AnimatedTaskView(@NonNull Context context, @Nullable AttributeSet attrs) {
@Nullable AttributeSet attrs) { this(context, attrs, 0);
super(context, attrs);
} }
public AnimatedTaskView( public AnimatedTaskView(
@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); this(context, attrs, defStyleAttr, 0);
} }
public AnimatedTaskView( public AnimatedTaskView(
@@ -104,97 +86,6 @@ public class AnimatedTaskView extends ConstraintLayout {
setToSingleRowLayout(false); setToSingleRowLayout(false);
} }
void animateToFillScreen(@Nullable Runnable onAnimationEndCallback) {
if (mTaskViewOutlineProvider == null) {
// This is an illegal state.
return;
}
// calculate start and end corner radius
Outline startOutline = new Outline();
mTaskViewOutlineProvider.getOutline(this, startOutline);
Rect outlineStartRect = new Rect();
startOutline.getRect(outlineStartRect);
float outlineStartRadius = startOutline.getRadius();
final Display display = mContext.getDisplay();;
RoundedCorner corner = display.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT);
float outlineEndRadius = corner.getRadius();
// create animation
AnimatorSet set = new AnimatorSet();
ArrayList<Animator> animations = new ArrayList<>();
// center view
animations.add(ObjectAnimator.ofFloat(this, TRANSLATION_X, 0));
// retrieve start animation matrix to scale off of
Matrix matrix = getAnimationMatrix();
if (matrix == null) {
// This is an illegal state.
return;
}
float[] matrixValues = new float[9];
matrix.getValues(matrixValues);
float[] newValues = matrixValues.clone();
ValueAnimator transformAnimation = ValueAnimator.ofFloat(0, 1);
MultiValueUpdateListener listener = new MultiValueUpdateListener() {
Matrix currentMatrix = new Matrix();
FloatProp mOutlineRadius = new FloatProp(outlineStartRadius, outlineEndRadius, 0,
ANIMATE_TO_FULL_SCREEN_DURATION, LINEAR);
FloatProp mTransX = new FloatProp(matrixValues[Matrix.MTRANS_X], 0f, 0,
ANIMATE_TO_FULL_SCREEN_DURATION, LINEAR);
FloatProp mTransY = new FloatProp(matrixValues[Matrix.MTRANS_Y], 0f, 0,
ANIMATE_TO_FULL_SCREEN_DURATION, LINEAR);
FloatProp mScaleX = new FloatProp(matrixValues[Matrix.MSCALE_X], 1f, 0,
ANIMATE_TO_FULL_SCREEN_DURATION, LINEAR);
FloatProp mScaleY = new FloatProp(matrixValues[Matrix.MSCALE_Y], 1f, 0,
ANIMATE_TO_FULL_SCREEN_DURATION, LINEAR);
@Override
public void onUpdate(float percent, boolean initOnly) {
// scale corner radius to match display radius
mTaskViewAnimatedRadius = mOutlineRadius.value;
mFullTaskView.invalidateOutline();
// translate to center, ends at translation x:0, y:0
newValues[Matrix.MTRANS_X] = mTransX.value;
newValues[Matrix.MTRANS_Y] = mTransY.value;
// scale to full size, ends at scale 1
newValues[Matrix.MSCALE_X] = mScaleX.value;
newValues[Matrix.MSCALE_Y] = mScaleY.value;
// create and set new animation matrix
currentMatrix.setValues(newValues);
setAnimationMatrix(currentMatrix);
}
};
transformAnimation.addUpdateListener(listener);
animations.add(transformAnimation);
set.playSequentially(animations);
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
addAnimatedOutlineProvider(mFullTaskView, outlineStartRect, outlineStartRadius);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if (onAnimationEndCallback != null) {
onAnimationEndCallback.run();
}
}
});
set.start();
}
AnimatorSet createAnimationToMultiRowLayout() { AnimatorSet createAnimationToMultiRowLayout() {
if (mTaskViewOutlineProvider == null) { if (mTaskViewOutlineProvider == null) {
// This is an illegal state. // This is an illegal state.
@@ -136,7 +136,7 @@ final class BackGestureTutorialController extends TutorialController {
} }
@Override @Override
protected int getSwipeActionColor() { protected int getFakeLauncherColor() {
return mTutorialFragment.mRootView.mColorSurfaceContainer; return mTutorialFragment.mRootView.mColorSurfaceContainer;
} }
@@ -104,11 +104,9 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
@Override @Override
protected int getMockAppTaskLayoutResId() { protected int getMockAppTaskLayoutResId() {
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get() return mTutorialFragment.isLargeScreen()
? R.layout.swipe_up_gesture_tutorial_shape ? R.layout.gesture_tutorial_tablet_mock_webpage
: mTutorialFragment.isLargeScreen() : R.layout.gesture_tutorial_mock_webpage;
? R.layout.gesture_tutorial_tablet_mock_webpage
: R.layout.gesture_tutorial_mock_webpage;
} }
@Override @Override
@@ -121,7 +119,12 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
} }
@Override @Override
protected int getSwipeActionColor() { protected int getFakeTaskViewColor() {
return isGestureCompleted() ? getFakeLauncherColor() : getExitingAppColor();
}
@Override
protected int getFakeLauncherColor() {
return mTutorialFragment.mRootView.mColorSurfaceContainer; return mTutorialFragment.mRootView.mColorSurfaceContainer;
} }
@@ -148,7 +151,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
case BACK_CANCELLED_FROM_LEFT: case BACK_CANCELLED_FROM_LEFT:
case BACK_CANCELLED_FROM_RIGHT: case BACK_CANCELLED_FROM_RIGHT:
case BACK_NOT_STARTED_TOO_FAR_FROM_EDGE: case BACK_NOT_STARTED_TOO_FAR_FROM_EDGE:
resetTaskView(); resetTaskViews();
showFeedback(R.string.home_gesture_feedback_swipe_too_far_from_edge); showFeedback(R.string.home_gesture_feedback_swipe_too_far_from_edge);
break; break;
} }
@@ -178,18 +181,18 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
} }
case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE: case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE:
case OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE: case OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE:
resetTaskView(); resetTaskViews();
showFeedback(R.string.home_gesture_feedback_swipe_too_far_from_edge); showFeedback(R.string.home_gesture_feedback_swipe_too_far_from_edge);
break; break;
case OVERVIEW_GESTURE_COMPLETED: case OVERVIEW_GESTURE_COMPLETED:
fadeOutFakeTaskView(true, true, () -> { fadeOutFakeTaskView(true, () -> {
showFeedback(R.string.home_gesture_feedback_overview_detected); showFeedback(R.string.home_gesture_feedback_overview_detected);
showFakeTaskbar(/* animateFromHotseat= */ false); showFakeTaskbar(/* animateFromHotseat= */ false);
}); });
break; break;
case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION: case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
case HOME_OR_OVERVIEW_CANCELLED: case HOME_OR_OVERVIEW_CANCELLED:
fadeOutFakeTaskView(false, true, null); fadeOutFakeTaskView(false, null);
showFeedback(R.string.home_gesture_feedback_wrong_swipe_direction); showFeedback(R.string.home_gesture_feedback_wrong_swipe_direction);
break; break;
} }
@@ -25,7 +25,9 @@ import android.annotation.TargetApi;
import android.graphics.PointF; import android.graphics.PointF;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.view.View;
import androidx.annotation.ColorInt;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
@@ -43,6 +45,8 @@ import java.util.Map;
@TargetApi(Build.VERSION_CODES.R) @TargetApi(Build.VERSION_CODES.R)
final class OverviewGestureTutorialController extends SwipeUpGestureTutorialController { final class OverviewGestureTutorialController extends SwipeUpGestureTutorialController {
private static final float LAUNCHER_COLOR_BLENDING_RATIO = 0.4f;
OverviewGestureTutorialController(OverviewGestureTutorialFragment fragment, OverviewGestureTutorialController(OverviewGestureTutorialFragment fragment,
TutorialType tutorialType) { TutorialType tutorialType) {
super(fragment, tutorialType); super(fragment, tutorialType);
@@ -112,11 +116,9 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
@Override @Override
protected int getMockAppTaskLayoutResId() { protected int getMockAppTaskLayoutResId() {
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get() return mTutorialFragment.isLargeScreen()
? R.layout.gesture_tutorial_mock_task_view ? R.layout.gesture_tutorial_tablet_mock_conversation_list
: mTutorialFragment.isLargeScreen() : R.layout.gesture_tutorial_mock_conversation_list;
? R.layout.gesture_tutorial_tablet_mock_conversation_list
: R.layout.gesture_tutorial_mock_conversation_list;
} }
@Override @Override
@@ -128,11 +130,31 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
: R.raw.overview_gesture_tutorial_animation; : R.raw.overview_gesture_tutorial_animation;
} }
@Override @ColorInt
protected int getSwipeActionColor() { private int getFakeTaskViewStartColor() {
return mTutorialFragment.mRootView.mColorSurfaceOverview; return mTutorialFragment.mRootView.mColorSurfaceOverview;
} }
@ColorInt
private int getFakeTaskViewEndColor() {
return getMockPreviousAppTaskThumbnailColor();
}
@Override
protected int getFakeTaskViewColor() {
return isGestureCompleted()
? getFakeTaskViewEndColor()
: getFakeTaskViewStartColor();
}
@Override
protected int getFakeLauncherColor() {
return ColorUtils.blendARGB(
mTutorialFragment.mRootView.mColorSurfaceContainer,
mTutorialFragment.mRootView.mColorOnSurfaceOverview,
LAUNCHER_COLOR_BLENDING_RATIO);
}
@Override @Override
protected int getHotseatIconColor() { protected int getHotseatIconColor() {
return mTutorialFragment.mRootView.mColorOnSurfaceOverview; return mTutorialFragment.mRootView.mColorOnSurfaceOverview;
@@ -159,7 +181,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
case BACK_CANCELLED_FROM_LEFT: case BACK_CANCELLED_FROM_LEFT:
case BACK_CANCELLED_FROM_RIGHT: case BACK_CANCELLED_FROM_RIGHT:
case BACK_NOT_STARTED_TOO_FAR_FROM_EDGE: case BACK_NOT_STARTED_TOO_FAR_FROM_EDGE:
resetTaskView(); resetTaskViews();
showFeedback(R.string.overview_gesture_feedback_swipe_too_far_from_edge); showFeedback(R.string.overview_gesture_feedback_swipe_too_far_from_edge);
break; break;
} }
@@ -190,7 +212,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
} }
case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE: case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE:
case OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE: case OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE:
resetTaskView(); resetTaskViews();
showFeedback(R.string.overview_gesture_feedback_swipe_too_far_from_edge); showFeedback(R.string.overview_gesture_feedback_swipe_too_far_from_edge);
break; break;
case OVERVIEW_GESTURE_COMPLETED: case OVERVIEW_GESTURE_COMPLETED:
@@ -204,7 +226,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
break; break;
case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION: case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
case HOME_OR_OVERVIEW_CANCELLED: case HOME_OR_OVERVIEW_CANCELLED:
fadeOutFakeTaskView(false, true, null); fadeOutFakeTaskView(false, null);
showFeedback(R.string.overview_gesture_feedback_wrong_swipe_direction); showFeedback(R.string.overview_gesture_feedback_wrong_swipe_direction);
break; break;
} }
@@ -229,15 +251,21 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
anim.addListener(new AnimatorListenerAdapter() { anim.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animator) { public void onAnimationEnd(Animator animator) {
new Handler().postDelayed(() -> { new Handler().postDelayed(
mFakeTaskView.setVisibility(View.INVISIBLE); () -> fadeOutFakeTaskView(
if (!mTutorialFragment.isLargeScreen()) { /* toOverviewFirst= */ true,
mFakePreviousTaskView.animateToFillScreen( /* animatePreviousTask= */ false,
() -> onSuccessAnimationComplete()); /* resetViews= */ false,
} else { /* updateListener= */ v -> mFakeTaskView.setBackgroundColor(
onSuccessAnimationComplete(); ColorUtils.blendARGB(
} getFakeTaskViewStartColor(),
}, TASK_VIEW_FILL_SCREEN_ANIMATION_DELAY_MILLIS); getFakeTaskViewEndColor(),
v.getAnimatedFraction())),
/* onEndRunnable= */ () -> {
showSuccessFeedback();
resetTaskViews();
}),
TASK_VIEW_FILL_SCREEN_ANIMATION_DELAY_MILLIS);
} }
}); });
} }
@@ -259,9 +287,4 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
animset.start(); animset.start();
mRunningWindowAnim = SwipeUpAnimationLogic.RunningWindowAnim.wrap(animset); mRunningWindowAnim = SwipeUpAnimationLogic.RunningWindowAnim.wrap(animset);
} }
private void onSuccessAnimationComplete() {
mFakeLauncherView.setBackgroundColor(getMockPreviousAppTaskThumbnailColor());
showSuccessFeedback();
}
} }
@@ -78,7 +78,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
private final AnimatorListenerAdapter mResetTaskView = new AnimatorListenerAdapter() { private final AnimatorListenerAdapter mResetTaskView = new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
resetTaskView(); resetTaskViews();
} }
}; };
@@ -122,7 +122,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
mRunningWindowAnim = null; mRunningWindowAnim = null;
} }
void resetTaskView() { void resetTaskViews() {
mFakeHotseatView.setVisibility(View.INVISIBLE); mFakeHotseatView.setVisibility(View.INVISIBLE);
mFakeIconView.setVisibility(View.INVISIBLE); mFakeIconView.setVisibility(View.INVISIBLE);
if (mTutorialFragment.getActivity() != null) { if (mTutorialFragment.getActivity() != null) {
@@ -141,10 +141,21 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
mShowPreviousTasks = false; mShowPreviousTasks = false;
mRunningWindowAnim = null; mRunningWindowAnim = null;
} }
void fadeOutFakeTaskView(boolean toOverviewFirst, @Nullable Runnable onEndRunnable) {
fadeOutFakeTaskView(
toOverviewFirst,
/* animatePreviousTask= */ true,
/* resetViews= */ true,
/* updateListener= */ null,
onEndRunnable);
}
/** Fades the task view, optionally after animating to a fake Overview. */ /** Fades the task view, optionally after animating to a fake Overview. */
void fadeOutFakeTaskView(boolean toOverviewFirst, boolean reset, void fadeOutFakeTaskView(boolean toOverviewFirst,
@Nullable Runnable onEndRunnable) { boolean animatePreviousTask,
boolean resetViews,
@Nullable ValueAnimator.AnimatorUpdateListener updateListener,
@Nullable Runnable onEndRunnable) {
cancelRunningAnimation(); cancelRunningAnimation();
PendingAnimation anim = new PendingAnimation(300); PendingAnimation anim = new PendingAnimation(300);
if (toOverviewFirst) { if (toOverviewFirst) {
@@ -155,20 +166,20 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
public void onAnimationEnd(Animator animation, boolean isReverse) { public void onAnimationEnd(Animator animation, boolean isReverse) {
PendingAnimation fadeAnim = PendingAnimation fadeAnim =
new PendingAnimation(TASK_VIEW_END_ANIMATION_DURATION_MILLIS); new PendingAnimation(TASK_VIEW_END_ANIMATION_DURATION_MILLIS);
if (reset) { fadeAnim.setFloat(mTaskViewSwipeUpAnimation
fadeAnim.setFloat(mTaskViewSwipeUpAnimation .getCurrentShift(), AnimatedFloat.VALUE, 0, ACCEL);
.getCurrentShift(), AnimatedFloat.VALUE, 0, ACCEL); if (resetViews) {
fadeAnim.addListener(mResetTaskView); fadeAnim.addListener(mResetTaskView);
} else {
fadeAnim.setViewAlpha(mFakeTaskView, 0, ACCEL);
fadeAnim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL);
} }
if (onEndRunnable != null) { if (onEndRunnable != null) {
fadeAnim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable)); fadeAnim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable));
} }
if (updateListener != null) {
fadeAnim.addOnFrameListener(updateListener);
}
AnimatorSet animset = fadeAnim.buildAnim(); AnimatorSet animset = fadeAnim.buildAnim();
if (reset && mTutorialFragment.isLargeScreen()) { if (animatePreviousTask && mTutorialFragment.isLargeScreen()) {
animset.addListener(new AnimatorListenerAdapter() { animset.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationStart(Animator animation) { public void onAnimationStart(Animator animation) {
@@ -190,13 +201,10 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
} }
}); });
} else { } else {
if (reset) { anim.setFloat(mTaskViewSwipeUpAnimation
anim.setFloat(mTaskViewSwipeUpAnimation .getCurrentShift(), AnimatedFloat.VALUE, 0, ACCEL);
.getCurrentShift(), AnimatedFloat.VALUE, 0, ACCEL); if (resetViews) {
anim.addListener(mResetTaskView); anim.addListener(mResetTaskView);
} else {
anim.setViewAlpha(mFakeTaskView, 0, ACCEL);
anim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL);
} }
if (onEndRunnable != null) { if (onEndRunnable != null) {
anim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable)); anim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable));
@@ -268,7 +268,12 @@ abstract class TutorialController implements BackGestureAttemptCallback,
} }
@ColorInt @ColorInt
protected abstract int getSwipeActionColor(); protected int getFakeTaskViewColor() {
return Color.TRANSPARENT;
}
@ColorInt
protected abstract int getFakeLauncherColor();
@ColorInt @ColorInt
protected int getExitingAppColor() { protected int getExitingAppColor() {
@@ -445,6 +450,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
} }
private void showSuccessPage() { private void showSuccessPage() {
pauseAndHideLottieAnimation();
mCheckmarkAnimation.setVisibility(View.VISIBLE); mCheckmarkAnimation.setVisibility(View.VISIBLE);
mCheckmarkAnimation.playAnimation(); mCheckmarkAnimation.playAnimation();
mFeedbackTitleView.setTextAppearance(mContext, getSuccessTitleTextAppearance()); mFeedbackTitleView.setTextAppearance(mContext, getSuccessTitleTextAppearance());
@@ -591,7 +597,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
protected void resetViewsForBackGesture() { protected void resetViewsForBackGesture() {
mFakeTaskView.setVisibility(View.VISIBLE); mFakeTaskView.setVisibility(View.VISIBLE);
mFakeTaskView.setBackgroundColor(getSwipeActionColor()); mFakeTaskView.setBackgroundColor(getFakeTaskViewColor());
mExitingAppView.setVisibility(View.VISIBLE); mExitingAppView.setVisibility(View.VISIBLE);
// reset the exiting app's dimensions // reset the exiting app's dimensions
@@ -690,11 +696,10 @@ abstract class TutorialController implements BackGestureAttemptCallback,
mContext, getMockWallpaperResId())); mContext, getMockWallpaperResId()));
mTutorialFragment.updateFeedbackAnimation(); mTutorialFragment.updateFeedbackAnimation();
mFakeLauncherView.setBackgroundColor(ENABLE_NEW_GESTURE_NAV_TUTORIAL.get() mFakeLauncherView.setBackgroundColor(ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
? getSwipeActionColor() ? getFakeLauncherColor()
: mContext.getColor(R.color.gesture_tutorial_fake_wallpaper_color)); : mContext.getColor(R.color.gesture_tutorial_fake_wallpaper_color));
updateFakeViewLayout(mFakeHotseatView, getMockHotseatResId()); updateFakeViewLayout(mFakeHotseatView, getMockHotseatResId());
mHotseatIconView = mFakeHotseatView.findViewById(R.id.hotseat_icon_1); mHotseatIconView = mFakeHotseatView.findViewById(R.id.hotseat_icon_1);
updateFakeViewLayout(mFakeTaskView, getMockAppTaskLayoutResId());
mFakeTaskView.animate().alpha(1).setListener( mFakeTaskView.animate().alpha(1).setListener(
AnimatorListeners.forSuccessCallback(() -> mFakeTaskView.animate().cancel())); AnimatorListeners.forSuccessCallback(() -> mFakeTaskView.animate().cancel()));
mFakePreviousTaskView.setFakeTaskViewFillColor(getMockPreviousAppTaskThumbnailColor()); mFakePreviousTaskView.setFakeTaskViewFillColor(getMockPreviousAppTaskThumbnailColor());
@@ -703,12 +708,15 @@ abstract class TutorialController implements BackGestureAttemptCallback,
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) { if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
mExitingAppView.setBackgroundColor(getExitingAppColor()); mExitingAppView.setBackgroundColor(getExitingAppColor());
mFakeTaskView.setBackgroundColor(getFakeTaskViewColor());
updateHotseatChildViewColor(mFakeIconView); updateHotseatChildViewColor(mFakeIconView);
updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_2)); updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_2));
updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_3)); updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_3));
updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_4)); updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_4));
updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_5)); updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_icon_5));
updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_search_bar)); updateHotseatChildViewColor(mFakeHotseatView.findViewById(R.id.hotseat_search_bar));
} else {
updateFakeViewLayout(mFakeTaskView, getMockAppTaskLayoutResId());
} }
} }
} }
@@ -143,6 +143,7 @@ abstract class TutorialFragment extends GestureSandboxFragment implements OnTouc
return null; return null;
} }
@NonNull
abstract TutorialController createController(TutorialType type); abstract TutorialController createController(TutorialType type);
abstract Class<? extends TutorialController> getControllerClass(); abstract Class<? extends TutorialController> getControllerClass();
@@ -374,9 +375,15 @@ abstract class TutorialFragment extends GestureSandboxFragment implements OnTouc
void changeController(TutorialType tutorialType) { void changeController(TutorialType tutorialType) {
if (getControllerClass().isInstance(mTutorialController)) { if (getControllerClass().isInstance(mTutorialController)) {
mTutorialController.setTutorialType(tutorialType); mTutorialController.setTutorialType(tutorialType);
if (isGestureComplete()) {
mTutorialController.setGestureCompleted();
}
mTutorialController.fadeTaskViewAndRun(mTutorialController::transitToController); mTutorialController.fadeTaskViewAndRun(mTutorialController::transitToController);
} else { } else {
mTutorialController = createController(tutorialType); mTutorialController = createController(tutorialType);
if (isGestureComplete()) {
mTutorialController.setGestureCompleted();
}
mTutorialController.transitToController(); mTutorialController.transitToController();
} }
mEdgeBackGestureHandler.registerBackGestureAttemptCallback(mTutorialController); mEdgeBackGestureHandler.registerBackGestureAttemptCallback(mTutorialController);