Merge "Redesign the tutorial for the go home gesture" into tm-qpr-dev am: 334094da9e
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/21150239 Change-Id: Ic9945132bfd6c048136dea36abbfcb846750d954 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -59,6 +59,12 @@ final class BackGestureTutorialController extends TutorialController {
|
||||
return getMockAppTaskCurrentPageLayoutResId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getGestureLottieAnimationId() {
|
||||
// TODO(b/253521922): Change to correct LottieAnimationView
|
||||
return R.raw.home_gesture_tutorial_animation;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
int getMockAppTaskCurrentPageLayoutResId() {
|
||||
return mTutorialFragment.isLargeScreen()
|
||||
@@ -73,6 +79,11 @@ final class BackGestureTutorialController extends TutorialController {
|
||||
: R.layout.gesture_tutorial_mock_conversation_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSwipeActionColorResId() {
|
||||
return R.color.gesture_back_tutorial_swipe_rect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackGestureAttempted(BackGestureResult result) {
|
||||
if (isGestureCompleted()) {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.quickstep.interaction;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.PointF;
|
||||
import android.os.Build;
|
||||
@@ -33,12 +35,16 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
|
||||
|
||||
@Override
|
||||
public int getIntroductionTitle() {
|
||||
return R.string.home_gesture_intro_title;
|
||||
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.string.home_gesture_tutorial_title
|
||||
: R.string.home_gesture_intro_title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntroductionSubtitle() {
|
||||
return R.string.home_gesture_intro_subtitle;
|
||||
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.string.home_gesture_tutorial_subtitle
|
||||
: R.string.home_gesture_intro_subtitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,7 +63,19 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
|
||||
protected int getMockAppTaskLayoutResId() {
|
||||
return mTutorialFragment.isLargeScreen()
|
||||
? R.layout.gesture_tutorial_tablet_mock_webpage
|
||||
: R.layout.gesture_tutorial_mock_webpage;
|
||||
: ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.layout.swipe_up_gesture_tutorial_shape
|
||||
: R.layout.gesture_tutorial_mock_webpage;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getGestureLottieAnimationId() {
|
||||
return R.raw.home_gesture_tutorial_animation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSwipeActionColorResId() {
|
||||
return R.color.gesture_home_tutorial_swipe_up_rect;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
@@ -70,6 +70,17 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
|
||||
: R.layout.gesture_tutorial_mock_conversation_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getGestureLottieAnimationId() {
|
||||
// TODO(b/253521660): Change to correct LottieAnimationView
|
||||
return R.raw.home_gesture_tutorial_animation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSwipeActionColorResId() {
|
||||
return R.color.gesture_overview_tutorial_swipe_rect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackGestureAttempted(BackGestureResult result) {
|
||||
if (isGestureCompleted()) {
|
||||
|
||||
@@ -19,12 +19,15 @@ import static android.view.View.GONE;
|
||||
import static android.view.View.NO_ID;
|
||||
import static android.view.View.inflate;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.ColorRes;
|
||||
import android.annotation.RawRes;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
@@ -57,6 +60,8 @@ import com.android.launcher3.views.ClipIconView;
|
||||
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
|
||||
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
@@ -85,6 +90,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
final Button mDoneButton;
|
||||
final ViewGroup mFeedbackView;
|
||||
final TextView mFeedbackTitleView;
|
||||
final TextView mFeedbackSubtitleView;
|
||||
final ImageView mEdgeGestureVideoView;
|
||||
final RelativeLayout mFakeLauncherView;
|
||||
final FrameLayout mFakeHotseatView;
|
||||
@@ -100,6 +106,8 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
private final AlertDialog mSkipTutorialDialog;
|
||||
|
||||
private boolean mGestureCompleted = false;
|
||||
private LottieAnimationView mAnimatedGestureDemonstration;
|
||||
private RelativeLayout mFullGestureDemonstration;
|
||||
|
||||
// These runnables should be used when posting callbacks to their views and cleared from their
|
||||
// views before posting new callbacks.
|
||||
@@ -120,6 +128,8 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
mFeedbackView = rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_view);
|
||||
mFeedbackTitleView = mFeedbackView.findViewById(
|
||||
R.id.gesture_tutorial_fragment_feedback_title);
|
||||
mFeedbackSubtitleView = mFeedbackView.findViewById(
|
||||
R.id.gesture_tutorial_fragment_feedback_subtitle);
|
||||
mEdgeGestureVideoView = rootView.findViewById(R.id.gesture_tutorial_edge_gesture_video);
|
||||
mFakeLauncherView = rootView.findViewById(R.id.gesture_tutorial_fake_launcher_view);
|
||||
mFakeHotseatView = rootView.findViewById(R.id.gesture_tutorial_fake_hotseat_view);
|
||||
@@ -136,6 +146,17 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
mFingerDotView = rootView.findViewById(R.id.gesture_tutorial_finger_dot);
|
||||
mSkipTutorialDialog = createSkipTutorialDialog();
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mAnimatedGestureDemonstration = mTutorialFragment.getRootView().findViewById(
|
||||
R.id.gesture_demonstration_animations);
|
||||
mFullGestureDemonstration = mTutorialFragment.getRootView().findViewById(
|
||||
R.id.full_gesture_demonstration);
|
||||
|
||||
mFeedbackTitleView.setText(getIntroductionTitle());
|
||||
mFeedbackSubtitleView.setText(getIntroductionSubtitle());
|
||||
mSkipButton.setVisibility(GONE);
|
||||
}
|
||||
|
||||
mTitleViewCallback = () -> mFeedbackTitleView.sendAccessibilityEvent(
|
||||
AccessibilityEvent.TYPE_VIEW_FOCUSED);
|
||||
mShowFeedbackRunnable = () -> {
|
||||
@@ -189,12 +210,19 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
? (mTutorialFragment.isFoldable()
|
||||
? R.layout.gesture_tutorial_foldable_mock_hotseat
|
||||
: R.layout.gesture_tutorial_tablet_mock_hotseat)
|
||||
: R.layout.gesture_tutorial_mock_hotseat;
|
||||
: (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.layout.redesigned_gesture_tutorial_mock_hotseat
|
||||
: R.layout.gesture_tutorial_mock_hotseat);
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
protected int getMockAppTaskLayoutResId() {
|
||||
return View.NO_ID;
|
||||
return NO_ID;
|
||||
}
|
||||
|
||||
@RawRes
|
||||
protected int getGestureLottieAnimationId() {
|
||||
return NO_ID;
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
@@ -202,9 +230,16 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
return R.color.gesture_tutorial_fake_previous_task_view_color;
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
protected int getSwipeActionColorResId() {
|
||||
return NO_ID;
|
||||
}
|
||||
|
||||
@DrawableRes
|
||||
public int getMockAppIconResId() {
|
||||
return R.drawable.default_sandbox_app_icon;
|
||||
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.drawable.redesigned_default_sandbox_app_icon
|
||||
: R.drawable.default_sandbox_app_icon;
|
||||
}
|
||||
|
||||
@DrawableRes
|
||||
@@ -301,9 +336,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
}
|
||||
|
||||
mFeedbackTitleView.setText(titleResId);
|
||||
TextView subtitle =
|
||||
mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_subtitle);
|
||||
subtitle.setText(spokenSubtitleResId == NO_ID
|
||||
mFeedbackSubtitleView.setText(spokenSubtitleResId == NO_ID
|
||||
? mContext.getText(subtitleResId)
|
||||
: Utilities.wrapForTts(
|
||||
mContext.getText(subtitleResId), mContext.getString(spokenSubtitleResId)));
|
||||
@@ -316,6 +349,10 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
mFakeTaskView.removeCallbacks(mFakeTaskViewCallback);
|
||||
mFakeTaskViewCallback = null;
|
||||
}
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
showSuccessPage();
|
||||
}
|
||||
}
|
||||
mGestureCompleted = isGestureSuccessful;
|
||||
|
||||
@@ -336,6 +373,16 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
mFeedbackView.post(mFeedbackViewCallback);
|
||||
}
|
||||
|
||||
private void showSuccessPage() {
|
||||
mFeedbackView.findViewById(
|
||||
R.id.gesture_tutorial_checkbox_bg).setVisibility(View.VISIBLE);
|
||||
mFeedbackView.findViewById(
|
||||
R.id.gesture_tutorial_checkbox).setVisibility(View.VISIBLE);
|
||||
mFeedbackTitleView.setTextAppearance(R.style.TextAppearance_GestureTutorial_SuccessTitle);
|
||||
mFeedbackSubtitleView.setTextAppearance(
|
||||
R.style.TextAppearance_GestureTutorial_SuccessSubtitle);
|
||||
}
|
||||
|
||||
public boolean isGestureCompleted() {
|
||||
return mGestureCompleted;
|
||||
}
|
||||
@@ -371,6 +418,14 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
@NonNull Runnable onStartRunnable,
|
||||
boolean useGestureAnimationDelay) {
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mFeedbackView.setVisibility(View.VISIBLE);
|
||||
mAnimatedGestureDemonstration.setVisibility(View.VISIBLE);
|
||||
mFullGestureDemonstration.setVisibility(View.VISIBLE);
|
||||
mAnimatedGestureDemonstration.playAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (gestureAnimation.isRunning()) {
|
||||
gestureAnimation.cancel();
|
||||
}
|
||||
@@ -436,19 +491,29 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
|
||||
@CallSuper
|
||||
void transitToController() {
|
||||
hideFeedback();
|
||||
hideActionButton();
|
||||
updateCloseButton();
|
||||
updateSubtext();
|
||||
updateDrawables();
|
||||
updateLayout();
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
startGestureAnimation();
|
||||
} else {
|
||||
hideFeedback();
|
||||
hideActionButton();
|
||||
}
|
||||
|
||||
mGestureCompleted = false;
|
||||
if (mFakeHotseatView != null) {
|
||||
mFakeHotseatView.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void startGestureAnimation() {
|
||||
mAnimatedGestureDemonstration.setAnimation(getGestureLottieAnimationId());
|
||||
mAnimatedGestureDemonstration.playAnimation();
|
||||
}
|
||||
|
||||
void updateCloseButton() {
|
||||
mSkipButton.setTextAppearance(Utilities.isDarkTheme(mContext)
|
||||
? R.style.TextAppearance_GestureTutorial_Feedback_Subtext
|
||||
@@ -512,8 +577,10 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
}
|
||||
|
||||
private void updateSubtext() {
|
||||
mTutorialStepView.setTutorialProgress(
|
||||
mTutorialFragment.getCurrentStep(), mTutorialFragment.getNumSteps());
|
||||
if (!ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mTutorialStepView.setTutorialProgress(
|
||||
mTutorialFragment.getCurrentStep(), mTutorialFragment.getNumSteps());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDrawables() {
|
||||
@@ -532,6 +599,11 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
getMockPreviousAppTaskThumbnailColorResId()));
|
||||
mFakeIconView.setBackground(AppCompatResources.getDrawable(
|
||||
mContext, getMockAppIconResId()));
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mFakeLauncherView.setBackgroundColor(
|
||||
mContext.getColor(getSwipeActionColorResId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,6 +758,12 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
return ValueAnimator.ofFloat(0f, 1f).setDuration(GESTURE_ANIMATION_PAUSE_DURATION_MILLIS);
|
||||
}
|
||||
|
||||
void pauseAndHideLottieAnimation() {
|
||||
mAnimatedGestureDemonstration.pauseAnimation();
|
||||
mAnimatedGestureDemonstration.setVisibility(View.INVISIBLE);
|
||||
mFullGestureDemonstration.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
/** Denotes the type of the tutorial. */
|
||||
enum TutorialType {
|
||||
BACK_NAVIGATION,
|
||||
|
||||
@@ -17,6 +17,8 @@ package com.android.quickstep.interaction;
|
||||
|
||||
import static android.view.View.NO_ID;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.app.Activity;
|
||||
@@ -184,7 +186,12 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
mRootView = (RootSandboxLayout) inflater.inflate(
|
||||
R.layout.gesture_tutorial_fragment, container, false);
|
||||
ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.layout.redesigned_gesture_tutorial_fragment
|
||||
: R.layout.gesture_tutorial_fragment,
|
||||
container,
|
||||
false);
|
||||
|
||||
mRootView.setOnApplyWindowInsetsListener((view, insets) -> {
|
||||
Insets systemInsets = insets.getInsets(WindowInsets.Type.systemBars());
|
||||
mEdgeBackGestureHandler.setInsets(systemInsets.left, systemInsets.right);
|
||||
@@ -333,6 +340,11 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
||||
if (mTutorialController != null && !isGestureComplete()) {
|
||||
mTutorialController.hideFeedback();
|
||||
}
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mTutorialController.pauseAndHideLottieAnimation();
|
||||
}
|
||||
|
||||
// Note: Using logical-or to ensure both functions get called.
|
||||
return mEdgeBackGestureHandler.onTouch(view, motionEvent)
|
||||
| mNavBarGestureHandler.onTouch(view, motionEvent);
|
||||
|
||||
Reference in New Issue
Block a user