Redesign the gesture tutorial for the Back gesture
This change adds in a new animation and layout to change the existing back tutorial as part of the effort to redesign gesture navigation education for users. This temporarily uses placeholder animations for the overview gesture. Large screen animations are also added for Home and Back tutorial. Flag: ENABLE_NEW_GESTURE_NAV_TUTORIAL Bug: 241813570 Bug: 253521922 Bug: 253520701 Test: Manual Change-Id: Ied18b88a83a3b673a7cf40fd33b6013f24998e44
This commit is contained in:
parent
f22345eace
commit
fd79b4dfbd
|
@ -103,6 +103,7 @@
|
|||
<activity android:name="com.android.quickstep.interaction.GestureSandboxActivity"
|
||||
android:autoRemoveFromRecents="true"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/GestureTutorialActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.quickstep.action.GESTURE_SANDBOX"/>
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<?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.
|
||||
-->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingVertical="26dp"
|
||||
android:paddingHorizontal="56dp">
|
||||
|
||||
<View
|
||||
android:id="@+id/hotseat_icon_1"
|
||||
android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:background="@drawable/hotseat_icon_home"
|
||||
android:clipToOutline="true"
|
||||
|
||||
app:layout_constraintBottom_toTopOf="@id/hotseat_icon_2"
|
||||
app:layout_constraintVertical_chainStyle="spread_inside"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/hotseat_icon_2"
|
||||
android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:background="@drawable/hotseat_icon_home"
|
||||
android:clipToOutline="true"
|
||||
|
||||
app:layout_constraintBottom_toTopOf="@id/hotseat_icon_3"
|
||||
app:layout_constraintTop_toBottomOf="@id/hotseat_icon_1"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/hotseat_icon_3"
|
||||
android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:background="@drawable/hotseat_icon_home"
|
||||
android:clipToOutline="true"
|
||||
|
||||
app:layout_constraintBottom_toTopOf="@id/hotseat_icon_4"
|
||||
app:layout_constraintTop_toBottomOf="@id/hotseat_icon_2"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/hotseat_icon_4"
|
||||
android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:background="@drawable/hotseat_icon_home"
|
||||
android:clipToOutline="true"
|
||||
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/hotseat_icon_3"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,18 @@
|
|||
<?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:id="@+id/back_gesture_tutorial_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
|
@ -118,6 +118,14 @@
|
|||
android:scaleType="fitXY"
|
||||
android:visibility="gone" />
|
||||
|
||||
<View
|
||||
android:id="@+id/exiting_app_back"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@color/gesture_back_tutorial_exiting_app"
|
||||
android:visibility="gone" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/full_gesture_demonstration"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -193,43 +201,33 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_fragment_feedback_subtitle" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/gesture_tutorial_checkbox_bg"
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/checkmark_animation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="48dp"
|
||||
android:layout_marginTop="100dp"
|
||||
android:background="@drawable/gesture_tutorial_complete_checkmark_bg"
|
||||
android:gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
app:lottie_loop="false"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/gesture_tutorial_fragment_action_button"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_fragment_feedback_subtitle" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/gesture_tutorial_checkbox"
|
||||
android:layout_width="124dp"
|
||||
android:layout_height="124dp"
|
||||
android:background="@drawable/gesture_tutorial_complete_checkmark"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/gesture_tutorial_checkbox_bg"
|
||||
app:layout_constraintEnd_toEndOf="@id/gesture_tutorial_checkbox_bg"
|
||||
app:layout_constraintStart_toStartOf="@id/gesture_tutorial_checkbox_bg"
|
||||
app:layout_constraintTop_toTopOf="@id/gesture_tutorial_checkbox_bg" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/gesture_tutorial_fragment_action_button"
|
||||
style="@style/TextAppearance.GestureTutorial.ButtonLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="48dp"
|
||||
android:background="@drawable/gesture_tutorial_action_button_background"
|
||||
android:stateListAnimator="@null"
|
||||
android:text="@string/gesture_tutorial_action_button_label"
|
||||
android:visibility="gone"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_checkbox_bg" />
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/checkmark_animation" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -45,8 +45,8 @@
|
|||
<!-- Redesigned gesture navigation tutorial -->
|
||||
<color name="gesture_home_tutorial_background">#FFB399</color>
|
||||
<color name="gesture_home_tutorial_swipe_up_rect">#3857C7</color>
|
||||
<color name="gesture_back_tutorial_background">#F3A5B9</color>
|
||||
<color name="gesture_back_tutorial_swipe_rect">#217500</color>
|
||||
<color name="gesture_back_tutorial_exiting_app">#F3A5B9</color>
|
||||
<color name="gesture_back_tutorial_background">#3857C7</color>
|
||||
<color name="gesture_overview_tutorial_swipe_rect">#7E44AD</color>
|
||||
|
||||
<!-- Mock hotseat -->
|
||||
|
|
|
@ -121,6 +121,8 @@
|
|||
<dimen name="gesture_tutorial_multi_row_task_view_spacing">72dp</dimen>
|
||||
<dimen name="gesture_tutorial_small_task_view_corner_radius">18dp</dimen>
|
||||
<dimen name="gesture_tutorial_mock_taskbar_height">80dp</dimen>
|
||||
<dimen name="gesture_tutorial_back_gesture_exiting_app_margin">8dp</dimen>
|
||||
<dimen name="gesture_tutorial_back_gesture_end_corner_radius">36dp</dimen>
|
||||
|
||||
<!-- Gesture Tutorial mock conversations -->
|
||||
<dimen name="gesture_tutorial_message_icon_size">44dp</dimen>
|
||||
|
|
|
@ -120,6 +120,8 @@
|
|||
<string name="back_gesture_intro_subtitle">To go back to the last screen, swipe from the left or right edge to the middle of the screen.</string>
|
||||
<!-- Introduction subtitle for the Back gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=200] -->
|
||||
<string name="back_gesture_spoken_intro_subtitle">To go back to the last screen, swipe with 2 fingers from the left or right edge to the middle of the screen.</string>
|
||||
<!-- Title of the gesture tutorial section educating users on how to go back to the previous screen. [CHAR LIMIT=100] -->
|
||||
<string name="back_gesture_tutorial_title">Go back</string>
|
||||
|
||||
<string name="home_gesture_feedback_swipe_too_far_from_edge">Make sure you swipe up from the bottom edge of the screen.</string>
|
||||
<!-- Feedback shown during interactive parts of Home gesture tutorial when the Overview gesture is detected. [CHAR LIMIT=100] -->
|
||||
|
|
|
@ -230,4 +230,9 @@
|
|||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
<item name="lineHeight">20sp</item>
|
||||
</style>
|
||||
|
||||
<style name="GestureTutorialActivity"
|
||||
parent="@style/AppTheme">
|
||||
<item name="background">@android:color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
@ -15,18 +15,24 @@
|
|||
*/
|
||||
package com.android.quickstep.interaction;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
|
||||
import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION;
|
||||
import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION_COMPLETE;
|
||||
|
||||
import android.annotation.LayoutRes;
|
||||
import android.graphics.PointF;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
|
||||
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
|
||||
|
||||
/** A {@link TutorialController} for the Back tutorial. */
|
||||
final class BackGestureTutorialController extends TutorialController {
|
||||
private static final float Y_TRANSLATION_SMOOTHENING_FACTOR = .2f;
|
||||
private static final float EXITING_APP_MIN_SIZE_PERCENTAGE = .8f;
|
||||
|
||||
BackGestureTutorialController(BackGestureTutorialFragment fragment, TutorialType tutorialType) {
|
||||
super(fragment, tutorialType);
|
||||
|
@ -34,7 +40,9 @@ final class BackGestureTutorialController extends TutorialController {
|
|||
|
||||
@Override
|
||||
public int getIntroductionTitle() {
|
||||
return R.string.back_gesture_intro_title;
|
||||
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.string.back_gesture_tutorial_title
|
||||
: R.string.back_gesture_intro_title;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,27 +69,32 @@ final class BackGestureTutorialController extends TutorialController {
|
|||
|
||||
@Override
|
||||
protected int getGestureLottieAnimationId() {
|
||||
// TODO(b/253521922): Change to correct LottieAnimationView
|
||||
return R.raw.home_gesture_tutorial_animation;
|
||||
return mTutorialFragment.isLargeScreen()
|
||||
? R.raw.back_gesture_tutorial_tablet_animation
|
||||
: R.raw.back_gesture_tutorial_animation;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
int getMockAppTaskCurrentPageLayoutResId() {
|
||||
return mTutorialFragment.isLargeScreen()
|
||||
? R.layout.gesture_tutorial_tablet_mock_conversation
|
||||
: R.layout.gesture_tutorial_mock_conversation;
|
||||
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.layout.back_gesture_tutorial_background
|
||||
: mTutorialFragment.isLargeScreen()
|
||||
? R.layout.gesture_tutorial_tablet_mock_conversation
|
||||
: R.layout.gesture_tutorial_mock_conversation;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
int getMockAppTaskPreviousPageLayoutResId() {
|
||||
return mTutorialFragment.isLargeScreen()
|
||||
? R.layout.gesture_tutorial_tablet_mock_conversation_list
|
||||
: R.layout.gesture_tutorial_mock_conversation_list;
|
||||
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.layout.back_gesture_tutorial_background
|
||||
: mTutorialFragment.isLargeScreen()
|
||||
? R.layout.gesture_tutorial_tablet_mock_conversation_list
|
||||
: R.layout.gesture_tutorial_mock_conversation_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSwipeActionColorResId() {
|
||||
return R.color.gesture_back_tutorial_swipe_rect;
|
||||
return R.color.gesture_back_tutorial_background;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -102,11 +115,59 @@ final class BackGestureTutorialController extends TutorialController {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackGestureProgress(float diffx, float diffy, boolean isLeftGesture) {
|
||||
if (isGestureCompleted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
float normalizedSwipeProgress = Math.abs(diffx / mScreenWidth);
|
||||
float smoothedExitingAppScale = Utilities.mapBoundToRange(
|
||||
normalizedSwipeProgress,
|
||||
/* lowerBound = */ 0f,
|
||||
/* upperBound = */ 1f,
|
||||
/* toMin = */ 1f,
|
||||
/* toMax = */ EXITING_APP_MIN_SIZE_PERCENTAGE,
|
||||
Interpolators.DEACCEL);
|
||||
|
||||
// shrink the exiting app as we progress through the back gesture
|
||||
mExitingAppView.setPivotX(isLeftGesture ? mScreenWidth : 0);
|
||||
mExitingAppView.setPivotY(mScreenHeight / 2f);
|
||||
mExitingAppView.setScaleX(smoothedExitingAppScale);
|
||||
mExitingAppView.setScaleY(smoothedExitingAppScale);
|
||||
mExitingAppView.setTranslationY(diffy * Y_TRANSLATION_SMOOTHENING_FACTOR);
|
||||
mExitingAppView.setTranslationX(Utilities.mapBoundToRange(
|
||||
normalizedSwipeProgress,
|
||||
/* lowerBound = */ 0f,
|
||||
/* upperBound = */ 1f,
|
||||
/* toMin = */ 0,
|
||||
/* toMax = */ mExitingAppMargin,
|
||||
Interpolators.DEACCEL)
|
||||
* (isLeftGesture ? -1 : 1));
|
||||
|
||||
// round the corners of the exiting app as we progress through the back gesture
|
||||
mExitingAppRadius = (int) Utilities.mapBoundToRange(
|
||||
normalizedSwipeProgress,
|
||||
/* lowerBound = */ 0f,
|
||||
/* upperBound = */ 1f,
|
||||
/* toMin = */ mExitingAppStartingCornerRadius,
|
||||
/* toMax = */ mExitingAppEndingCornerRadius,
|
||||
Interpolators.EMPHASIZED_DECELERATE);
|
||||
mExitingAppView.invalidateOutline();
|
||||
}
|
||||
|
||||
private void handleBackAttempt(BackGestureResult result) {
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
resetViewsForBackGesture();
|
||||
}
|
||||
|
||||
switch (result) {
|
||||
case BACK_COMPLETED_FROM_LEFT:
|
||||
case BACK_COMPLETED_FROM_RIGHT:
|
||||
mTutorialFragment.releaseFeedbackAnimation();
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mExitingAppView.setVisibility(View.GONE);
|
||||
}
|
||||
updateFakeAppTaskViewLayout(getMockAppTaskPreviousPageLayoutResId());
|
||||
showSuccessFeedback();
|
||||
break;
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package com.android.quickstep.interaction;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Point;
|
||||
|
@ -29,8 +31,8 @@ import android.view.ViewGroup.LayoutParams;
|
|||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.testing.shared.ResourceUtils;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.testing.shared.ResourceUtils;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
|
||||
/**
|
||||
|
@ -207,7 +209,11 @@ public class EdgeBackGestureHandler implements OnTouchListener {
|
|||
mThresholdCrossed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mGestureCallback.onBackGestureProgress(ev.getX() - mDownPoint.x,
|
||||
ev.getY() - mDownPoint.y, mEdgeBackPanel.getIsLeftPanel());
|
||||
}
|
||||
|
||||
// forward touch
|
||||
|
@ -242,5 +248,8 @@ public class EdgeBackGestureHandler implements OnTouchListener {
|
|||
interface BackGestureAttemptCallback {
|
||||
/** Called whenever any touch is completed. */
|
||||
void onBackGestureAttempted(BackGestureResult result);
|
||||
|
||||
/** Called when the back gesture is recognized and is in progress. */
|
||||
default void onBackGestureProgress(float diffx, float diffy, boolean isLeftGesture) {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,9 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
|
|||
|
||||
@Override
|
||||
protected int getGestureLottieAnimationId() {
|
||||
return R.raw.home_gesture_tutorial_animation;
|
||||
return mTutorialFragment.isLargeScreen()
|
||||
? R.raw.home_gesture_tutorial_tablet_animation
|
||||
: R.raw.home_gesture_tutorial_animation;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,12 +30,15 @@ import android.annotation.ColorRes;
|
|||
import android.annotation.RawRes;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
|
@ -59,6 +62,7 @@ import com.android.launcher3.anim.AnimatorListeners;
|
|||
import com.android.launcher3.views.ClipIconView;
|
||||
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
|
||||
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
|
||||
|
@ -81,6 +85,11 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
|||
private static final int GESTURE_ANIMATION_DELAY_MS = 1500;
|
||||
private static final int ADVANCE_TUTORIAL_TIMEOUT_MS = 2000;
|
||||
private static final long GESTURE_ANIMATION_PAUSE_DURATION_MILLIS = 1000;
|
||||
protected float mExitingAppEndingCornerRadius;
|
||||
protected float mExitingAppStartingCornerRadius;
|
||||
protected int mScreenHeight;
|
||||
protected float mScreenWidth;
|
||||
protected float mExitingAppMargin;
|
||||
|
||||
final TutorialFragment mTutorialFragment;
|
||||
TutorialType mTutorialType;
|
||||
|
@ -103,10 +112,14 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
|||
final RippleDrawable mRippleDrawable;
|
||||
final TutorialStepIndicator mTutorialStepView;
|
||||
final ImageView mFingerDotView;
|
||||
private final Rect mExitingAppRect = new Rect();
|
||||
protected View mExitingAppView;
|
||||
protected int mExitingAppRadius;
|
||||
private final AlertDialog mSkipTutorialDialog;
|
||||
|
||||
private boolean mGestureCompleted = false;
|
||||
private LottieAnimationView mAnimatedGestureDemonstration;
|
||||
private LottieAnimationView mCheckmarkAnimation;
|
||||
private RelativeLayout mFullGestureDemonstration;
|
||||
|
||||
// These runnables should be used when posting callbacks to their views and cleared from their
|
||||
|
@ -147,13 +160,28 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
|||
mSkipTutorialDialog = createSkipTutorialDialog();
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mAnimatedGestureDemonstration = mTutorialFragment.getRootView().findViewById(
|
||||
mFullGestureDemonstration = rootView.findViewById(R.id.full_gesture_demonstration);
|
||||
mCheckmarkAnimation = rootView.findViewById(R.id.checkmark_animation);
|
||||
mAnimatedGestureDemonstration = rootView.findViewById(
|
||||
R.id.gesture_demonstration_animations);
|
||||
mFullGestureDemonstration = mTutorialFragment.getRootView().findViewById(
|
||||
R.id.full_gesture_demonstration);
|
||||
mExitingAppView = rootView.findViewById(R.id.exiting_app_back);
|
||||
mScreenWidth = mTutorialFragment.getDeviceProfile().widthPx;
|
||||
mScreenHeight = mTutorialFragment.getDeviceProfile().heightPx;
|
||||
mExitingAppMargin = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.gesture_tutorial_back_gesture_exiting_app_margin);
|
||||
mExitingAppStartingCornerRadius = QuickStepContract.getWindowCornerRadius(mContext);
|
||||
mExitingAppEndingCornerRadius = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.gesture_tutorial_back_gesture_end_corner_radius);
|
||||
|
||||
mFeedbackTitleView.setText(getIntroductionTitle());
|
||||
mFeedbackSubtitleView.setText(getIntroductionSubtitle());
|
||||
mExitingAppView.setClipToOutline(true);
|
||||
mExitingAppView.setOutlineProvider(new ViewOutlineProvider() {
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline) {
|
||||
outline.setRoundRect(mExitingAppRect, mExitingAppRadius);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mTitleViewCallback = () -> mFeedbackTitleView.sendAccessibilityEvent(
|
||||
|
@ -373,10 +401,8 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
|||
}
|
||||
|
||||
private void showSuccessPage() {
|
||||
mFeedbackView.findViewById(
|
||||
R.id.gesture_tutorial_checkbox_bg).setVisibility(View.VISIBLE);
|
||||
mFeedbackView.findViewById(
|
||||
R.id.gesture_tutorial_checkbox).setVisibility(View.VISIBLE);
|
||||
mCheckmarkAnimation.setVisibility(View.VISIBLE);
|
||||
mCheckmarkAnimation.playAnimation();
|
||||
mFeedbackTitleView.setTextAppearance(R.style.TextAppearance_GestureTutorial_SuccessTitle);
|
||||
mFeedbackSubtitleView.setTextAppearance(
|
||||
R.style.TextAppearance_GestureTutorial_SuccessSubtitle);
|
||||
|
@ -496,7 +522,17 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
|||
updateLayout();
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
startGestureAnimation();
|
||||
mCheckmarkAnimation.setAnimation(mTutorialFragment.isAtFinalStep()
|
||||
? R.raw.checkmark_animation_end
|
||||
: R.raw.checkmark_animation_in_progress);
|
||||
if (!isGestureCompleted()) {
|
||||
mCheckmarkAnimation.setVisibility(GONE);
|
||||
startGestureAnimation();
|
||||
if (mTutorialType == TutorialType.BACK_NAVIGATION) {
|
||||
resetViewsForBackGesture();
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
hideFeedback();
|
||||
hideActionButton();
|
||||
|
@ -508,6 +544,23 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
|||
}
|
||||
}
|
||||
|
||||
protected void resetViewsForBackGesture() {
|
||||
mFakeTaskView.setVisibility(View.VISIBLE);
|
||||
mFakeTaskView.setBackgroundColor(
|
||||
mContext.getColor(R.color.gesture_back_tutorial_background));
|
||||
mExitingAppView.setVisibility(View.VISIBLE);
|
||||
|
||||
// reset the exiting app's dimensions
|
||||
mExitingAppRect.set(0, 0, (int) mScreenWidth, (int) mScreenHeight);
|
||||
mExitingAppRadius = 0;
|
||||
mExitingAppView.resetPivot();
|
||||
mExitingAppView.setScaleX(1f);
|
||||
mExitingAppView.setScaleY(1f);
|
||||
mExitingAppView.setTranslationX(0);
|
||||
mExitingAppView.setTranslationY(0);
|
||||
mExitingAppView.invalidateOutline();
|
||||
}
|
||||
|
||||
private void startGestureAnimation() {
|
||||
mAnimatedGestureDemonstration.setAnimation(getGestureLottieAnimationId());
|
||||
mAnimatedGestureDemonstration.playAnimation();
|
||||
|
|
|
@ -312,7 +312,6 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||
if (mEdgeAnimation != null && mEdgeAnimation.isRunning()) {
|
||||
mEdgeAnimation.stop();
|
||||
}
|
||||
|
||||
mEdgeGestureVideoView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue