Merge "Update gesture nav edu motion and colors" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b4e91b14bd
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-10
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
+48
-25
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-17
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user