mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-19 10:48:19 +00:00
Merge "Redesign the gesture tutorial for the Back gesture" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
60c419b9b7
@@ -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>
|
||||
18
quickstep/res/layout/back_gesture_tutorial_background.xml
Normal file
18
quickstep/res/layout/back_gesture_tutorial_background.xml
Normal file
@@ -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>
|
||||
|
||||
|
||||
1
quickstep/res/raw/back_gesture_tutorial_animation.json
Normal file
1
quickstep/res/raw/back_gesture_tutorial_animation.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
quickstep/res/raw/checkmark_animation_end.json
Normal file
1
quickstep/res/raw/checkmark_animation_end.json
Normal file
File diff suppressed because one or more lines are too long
1
quickstep/res/raw/checkmark_animation_in_progress.json
Normal file
1
quickstep/res/raw/checkmark_animation_in_progress.json
Normal file
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>
|
||||
|
||||
@@ -117,6 +117,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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user