Merge "Add mock animated taskbar to gesture nav tutorial for foldable devices." into sc-v2-dev

This commit is contained in:
TreeHugger Robot 2021-10-27 17:45:38 +00:00 committed by Android (Google) Code Review
commit 3edb8de094
13 changed files with 559 additions and 10 deletions

View File

@ -84,7 +84,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/mock_conversation_background"
android:paddingBottom="80dp"
android:paddingBottom="@dimen/gesture_tutorial_mock_taskbar_height"
app:layout_constraintTop_toBottomOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="parent"

View File

@ -51,7 +51,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/mock_list_background"
android:paddingBottom="80dp"
android:paddingBottom="@dimen/gesture_tutorial_mock_taskbar_height"
app:layout_constraintTop_toBottomOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="parent"

View File

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<com.android.quickstep.interaction.AnimatedTaskbarView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/gesture_tutorial_mock_taskbar_height">
<View
android:id="@+id/taskbar_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/gesture_tutorial_taskbar_color"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/icon_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<androidx.cardview.widget.CardView
android:id="@+id/taskbar_icon_1"
android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
android:layout_marginStart="@dimen/gesture_tutorial_taskbar_padding_start_end"
app:cardElevation="0dp"
app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
app:cardBackgroundColor="@color/mock_app_icon_1"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/taskbar_icon_2"/>
<androidx.cardview.widget.CardView
android:id="@+id/taskbar_icon_2"
android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
app:cardElevation="0dp"
app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
app:cardBackgroundColor="@color/mock_app_icon_2"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/taskbar_icon_1"
app:layout_constraintEnd_toStartOf="@id/taskbar_icon_3"/>
<androidx.cardview.widget.CardView
android:id="@+id/taskbar_icon_3"
android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
app:cardElevation="0dp"
app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
app:cardBackgroundColor="@color/mock_app_icon_3"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/taskbar_icon_2"
app:layout_constraintEnd_toStartOf="@id/taskbar_icon_4"/>
<androidx.cardview.widget.CardView
android:id="@+id/taskbar_icon_4"
android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
app:cardElevation="0dp"
app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
app:cardBackgroundColor="@color/mock_app_icon_1"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/taskbar_icon_3"
app:layout_constraintEnd_toStartOf="@id/taskbar_icon_5"/>
<androidx.cardview.widget.CardView
android:id="@+id/taskbar_icon_5"
android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
app:cardElevation="0dp"
app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
app:cardBackgroundColor="@color/mock_app_icon_4"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/taskbar_icon_4"
app:layout_constraintEnd_toStartOf="@id/taskbar_icon_6"/>
<androidx.cardview.widget.CardView
android:id="@+id/taskbar_icon_6"
android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
android:layout_marginEnd="@dimen/gesture_tutorial_taskbar_padding_start_end"
app:cardElevation="0dp"
app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
app:cardBackgroundColor="@color/mock_app_icon_2"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/taskbar_icon_5"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.android.quickstep.interaction.AnimatedTaskbarView>

View File

@ -101,6 +101,15 @@
android:layout_height="match_parent"
android:background="@drawable/gesture_tutorial_ripple"/>
<include
layout="@layout/gesture_tutorial_foldable_mock_taskbar"
android:id="@+id/gesture_tutorial_fake_taskbar_view"
android:layout_width="match_parent"
android:layout_height="@dimen/gesture_tutorial_mock_taskbar_height"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true" />
<ImageView
android:id="@+id/gesture_tutorial_edge_gesture_video"
android:layout_width="match_parent"

View File

@ -40,6 +40,7 @@
<color name="gesture_tutorial_fake_previous_task_view_color">#3C4043</color> <!-- Gray -->
<color name="gesture_tutorial_action_button_label_color">#FF000000</color>
<color name="gesture_tutorial_primary_color">#B7F29F</color> <!-- Light Green -->
<color name="gesture_tutorial_taskbar_color">#202124</color>
<!-- Mock hotseat -->
<color name="mock_app_icon_1">#8AB4F8</color>

View File

@ -121,6 +121,7 @@
<dimen name="gesture_tutorial_foldable_feedback_margin_start_end">140dp</dimen>
<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>
<!-- Gesture Tutorial mock conversations -->
<dimen name="gesture_tutorial_message_icon_size">44dp</dimen>
@ -155,6 +156,11 @@
<dimen name="gesture_tutorial_webpage_large_line_height">36dp</dimen>
<dimen name="gesture_tutorial_webpage_small_line_height">22dp</dimen>
<!-- Gesture Tutorial mock taskbar -->
<dimen name="gesture_tutorial_taskbar_icon_size">44dp</dimen>
<dimen name="gesture_tutorial_taskbar_icon_corner_radius">100dp</dimen>
<dimen name="gesture_tutorial_taskbar_padding_start_end">218dp</dimen>
<!-- All Set page -->
<dimen name="allset_page_margin_horizontal">40dp</dimen>
<dimen name="allset_title_margin_top">24dp</dimen>

View File

@ -0,0 +1,368 @@
/*
* Copyright (C) 2021 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.
*/
package com.android.quickstep.interaction;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.android.launcher3.R;
import java.util.ArrayList;
/**
* Helper View for the gesture tutorial mock taskbar view.
*
* This helper class allows animating this mock taskview to and from a mock hotseat and the bottom
* of the screen.
*/
public class AnimatedTaskbarView extends ConstraintLayout {
private View mBackground;
private View mIconContainer;
private View mIcon1;
private View mIcon2;
private View mIcon3;
private View mIcon4;
private View mIcon5;
private View mIcon6;
@Nullable private Animator mRunningAnimator;
public AnimatedTaskbarView(@NonNull Context context) {
super(context);
}
public AnimatedTaskbarView(@NonNull Context context,
@Nullable AttributeSet attrs) {
super(context, attrs);
}
public AnimatedTaskbarView(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public AnimatedTaskbarView(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mBackground = findViewById(R.id.taskbar_background);
mIconContainer = findViewById(R.id.icon_container);
mIcon1 = findViewById(R.id.taskbar_icon_1);
mIcon2 = findViewById(R.id.taskbar_icon_2);
mIcon3 = findViewById(R.id.taskbar_icon_3);
mIcon4 = findViewById(R.id.taskbar_icon_4);
mIcon5 = findViewById(R.id.taskbar_icon_5);
mIcon6 = findViewById(R.id.taskbar_icon_6);
}
/**
* Animates this fake taskbar's disappearance into the given hotseat view.
*/
public void animateDisappearanceToHotseat(ViewGroup hotseat) {
ArrayList<Animator> animators = new ArrayList<>();
int hotseatTop = hotseat.getTop();
animators.add(ObjectAnimator.ofFloat(
mBackground, View.TRANSLATION_Y, 0, mBackground.getHeight()));
animators.add(ObjectAnimator.ofFloat(mBackground, View.ALPHA, 1f, 0f));
animators.add(createIconDisappearanceToHotseatAnimator(
mIcon1, hotseat.findViewById(R.id.hotseat_icon_1), hotseatTop));
animators.add(createIconDisappearanceToHotseatAnimator(
mIcon2, hotseat.findViewById(R.id.hotseat_icon_2), hotseatTop));
animators.add(createIconDisappearanceToHotseatAnimator(
mIcon3, hotseat.findViewById(R.id.hotseat_icon_3), hotseatTop));
animators.add(createIconDisappearanceToHotseatAnimator(
mIcon4, hotseat.findViewById(R.id.hotseat_icon_4), hotseatTop));
animators.add(createIconDisappearanceToHotseatAnimator(
mIcon5, hotseat.findViewById(R.id.hotseat_icon_5), hotseatTop));
animators.add(createIconDisappearanceToHotseatAnimator(
mIcon6, hotseat.findViewById(R.id.hotseat_icon_6), hotseatTop));
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animators);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
setVisibility(INVISIBLE);
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
setVisibility(VISIBLE);
}
});
start(animatorSet);
}
/**
* Animates this fake taskbar's appearance from the given hotseat view.
*/
public void animateAppearanceFromHotseat(ViewGroup hotseat) {
ArrayList<Animator> animators = new ArrayList<>();
int hotseatTop = hotseat.getTop();
animators.add(ObjectAnimator.ofFloat(
mBackground, View.TRANSLATION_Y, mBackground.getHeight(), 0));
animators.add(ObjectAnimator.ofFloat(mBackground, View.ALPHA, 0f, 1f));
animators.add(createIconAppearanceFromHotseatAnimator(
mIcon1, hotseat.findViewById(R.id.hotseat_icon_1), hotseatTop));
animators.add(createIconAppearanceFromHotseatAnimator(
mIcon2, hotseat.findViewById(R.id.hotseat_icon_2), hotseatTop));
animators.add(createIconAppearanceFromHotseatAnimator(
mIcon3, hotseat.findViewById(R.id.hotseat_icon_3), hotseatTop));
animators.add(createIconAppearanceFromHotseatAnimator(
mIcon4, hotseat.findViewById(R.id.hotseat_icon_4), hotseatTop));
animators.add(createIconAppearanceFromHotseatAnimator(
mIcon5, hotseat.findViewById(R.id.hotseat_icon_5), hotseatTop));
animators.add(createIconAppearanceFromHotseatAnimator(
mIcon6, hotseat.findViewById(R.id.hotseat_icon_6), hotseatTop));
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animators);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
setVisibility(VISIBLE);
}
});
start(animatorSet);
}
/**
* Animates this fake taskbar's disappearance to the bottom of the screen.
*/
public void animateDisappearanceToBottom() {
ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofFloat(
mBackground, View.TRANSLATION_Y, 0, mBackground.getHeight()));
animators.add(ObjectAnimator.ofFloat(mBackground, View.ALPHA, 1f, 0f));
animators.add(ObjectAnimator.ofFloat(mIconContainer, View.SCALE_X, 1f, 0f));
animators.add(ObjectAnimator.ofFloat(mIconContainer, View.SCALE_Y, 1f, 0f));
initializeIconContainerPivot();
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animators);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
setVisibility(INVISIBLE);
resetIconContainerPivot();
}
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
resetIconContainerPivot();
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
setVisibility(VISIBLE);
}
});
start(animatorSet);
}
/**
* Animates this fake taskbar's appearance from the bottom of the screen.
*/
public void animateAppearanceFromBottom() {
ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofFloat(
mBackground, View.TRANSLATION_Y, mBackground.getHeight(), 0));
animators.add(ObjectAnimator.ofFloat(mBackground, View.ALPHA, 0f, 1f));
animators.add(ObjectAnimator.ofFloat(mIconContainer, View.SCALE_X, 0f, 1f));
animators.add(ObjectAnimator.ofFloat(mIconContainer, View.SCALE_Y, 0f, 1f));
initializeIconContainerPivot();
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animators);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
setVisibility(VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
resetIconContainerPivot();
}
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
resetIconContainerPivot();
}
});
start(animatorSet);
}
private void initializeIconContainerPivot() {
mIconContainer.setPivotX(getWidth() / 2f);
mIconContainer.setPivotY(getHeight() * 0.8f);
}
private void resetIconContainerPivot() {
mIconContainer.resetPivot();
mIconContainer.setScaleX(1f);
mIconContainer.setScaleY(1f);
}
private void start(Animator animator) {
if (mRunningAnimator != null) {
mRunningAnimator.cancel();
}
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
mRunningAnimator = null;
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mRunningAnimator = null;
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
mRunningAnimator = animator;
}
});
animator.start();
}
private Animator createIconDisappearanceToHotseatAnimator(
View taskbarIcon, View hotseatIcon, int hotseatTop) {
ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofFloat(
taskbarIcon,
View.TRANSLATION_Y,
0,
(hotseatTop + hotseatIcon.getTop()) - (getTop() + taskbarIcon.getTop())));
animators.add(ObjectAnimator.ofFloat(
taskbarIcon, View.TRANSLATION_X, 0, hotseatIcon.getLeft() - taskbarIcon.getLeft()));
animators.add(ObjectAnimator.ofFloat(
taskbarIcon,
View.SCALE_X,
1f,
(float) hotseatIcon.getWidth() / (float) taskbarIcon.getWidth()));
animators.add(ObjectAnimator.ofFloat(
taskbarIcon,
View.SCALE_Y,
1f,
(float) hotseatIcon.getHeight() / (float) taskbarIcon.getHeight()));
animators.add(ObjectAnimator.ofFloat(taskbarIcon, View.ALPHA, 1f, 0f));
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animators);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
taskbarIcon.setVisibility(INVISIBLE);
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
taskbarIcon.setVisibility(VISIBLE);
}
});
return animatorSet;
}
private Animator createIconAppearanceFromHotseatAnimator(
View taskbarIcon, View hotseatIcon, int hotseatTop) {
ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofFloat(
taskbarIcon,
View.TRANSLATION_Y,
(hotseatTop + hotseatIcon.getTop()) - (getTop() + taskbarIcon.getTop()),
0));
animators.add(ObjectAnimator.ofFloat(
taskbarIcon, View.TRANSLATION_X, hotseatIcon.getLeft() - taskbarIcon.getLeft(), 0));
animators.add(ObjectAnimator.ofFloat(
taskbarIcon,
View.SCALE_X,
(float) hotseatIcon.getWidth() / (float) taskbarIcon.getWidth(),
1f));
animators.add(ObjectAnimator.ofFloat(
taskbarIcon,
View.SCALE_Y,
(float) hotseatIcon.getHeight() / (float) taskbarIcon.getHeight(),
1f));
animators.add(ObjectAnimator.ofFloat(taskbarIcon, View.ALPHA, 0f, 1f));
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animators);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
taskbarIcon.setVisibility(VISIBLE);
}
});
return animatorSet;
}
}

View File

@ -95,8 +95,10 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
showFeedback(R.string.home_gesture_feedback_swipe_too_far_from_edge);
break;
case OVERVIEW_GESTURE_COMPLETED:
fadeOutFakeTaskView(true, true, () ->
showFeedback(R.string.home_gesture_feedback_overview_detected));
fadeOutFakeTaskView(true, true, () -> {
showFeedback(R.string.home_gesture_feedback_overview_detected);
showFakeTaskbar(/* animateFromHotseat= */ false);
});
break;
case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
case HOME_OR_OVERVIEW_CANCELLED:

View File

@ -61,7 +61,7 @@ public class HomeGestureTutorialFragment extends TutorialFragment {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
controller.resetFakeTaskView();
controller.resetFakeTaskView(true);
}
});
ArrayList<Animator> animators = new ArrayList<>();
@ -76,7 +76,7 @@ public class HomeGestureTutorialFragment extends TutorialFragment {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
controller.resetFakeTaskView();
controller.resetFakeTaskView(true);
}
});
finalAnimation.playSequentially(animators);

View File

@ -93,8 +93,8 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
switch (result) {
case HOME_GESTURE_COMPLETED: {
animateFakeTaskViewHome(finalVelocity, () -> {
resetFakeTaskView();
showFeedback(R.string.overview_gesture_feedback_home_detected);
resetFakeTaskView(true);
});
break;
}
@ -146,6 +146,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
AnimatorSet animset = new AnimatorSet();
animset.playTogether(animators);
hideFakeTaskbar(/* animateToHotseat= */ false);
animset.start();
mRunningWindowAnim = SwipeUpAnimationLogic.RunningWindowAnim.wrap(animset);
}

View File

@ -72,7 +72,7 @@ public class OverviewGestureTutorialFragment extends TutorialFragment {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
controller.resetFakeTaskView();
controller.resetFakeTaskView(false);
}
});
ArrayList<Animator> animators = new ArrayList<>();
@ -88,7 +88,7 @@ public class OverviewGestureTutorialFragment extends TutorialFragment {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
controller.resetFakeTaskView();
controller.resetFakeTaskView(false);
}
});
finalAnimation.playSequentially(animators);

View File

@ -198,11 +198,12 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
}
}
AnimatorSet animset = anim.buildAnim();
hideFakeTaskbar(/* animateToHotseat= */ false);
animset.start();
mRunningWindowAnim = RunningWindowAnim.wrap(animset);
}
void resetFakeTaskView() {
void resetFakeTaskView(boolean animateFromHome) {
mFakeTaskView.setVisibility(View.VISIBLE);
PendingAnimation anim = new PendingAnimation(300);
anim.setFloat(mTaskViewSwipeUpAnimation
@ -210,12 +211,14 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
anim.setViewAlpha(mFakeTaskView, 1, ACCEL);
anim.addListener(mResetTaskView);
AnimatorSet animset = anim.buildAnim();
showFakeTaskbar(animateFromHome);
animset.start();
mRunningWindowAnim = RunningWindowAnim.wrap(animset);
}
void animateFakeTaskViewHome(PointF finalVelocity, @Nullable Runnable onEndRunnable) {
cancelRunningAnimation();
hideFakeTaskbar(/* animateToHotseat= */ true);
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
mFakeHotseatView.setVisibility(View.VISIBLE);
mShowPreviousTasks = false;

View File

@ -89,6 +89,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
@Nullable View mHotseatIconView;
final ClipIconView mFakeIconView;
final FrameLayout mFakeTaskView;
final AnimatedTaskbarView mFakeTaskbarView;
final AnimatedTaskView mFakePreviousTaskView;
final View mRippleView;
final RippleDrawable mRippleDrawable;
@ -104,6 +105,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
private final Runnable mTitleViewCallback;
@Nullable private Runnable mFeedbackViewCallback;
@Nullable private Runnable mFakeTaskViewCallback;
@Nullable private Runnable mFakeTaskbarViewCallback;
private final Runnable mShowFeedbackRunnable;
TutorialController(TutorialFragment tutorialFragment, TutorialType tutorialType) {
@ -122,6 +124,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
mFakeHotseatView = rootView.findViewById(R.id.gesture_tutorial_fake_hotseat_view);
mFakeIconView = rootView.findViewById(R.id.gesture_tutorial_fake_icon_view);
mFakeTaskView = rootView.findViewById(R.id.gesture_tutorial_fake_task_view);
mFakeTaskbarView = rootView.findViewById(R.id.gesture_tutorial_fake_taskbar_view);
mFakePreviousTaskView =
rootView.findViewById(R.id.gesture_tutorial_fake_previous_task_view);
mRippleView = rootView.findViewById(R.id.gesture_tutorial_ripple_view);
@ -319,6 +322,10 @@ abstract class TutorialController implements BackGestureAttemptCallback,
mFakeTaskView.removeCallbacks(mFakeTaskViewCallback);
mFakeTaskViewCallback = null;
}
if (mFakeTaskbarViewCallback != null) {
mFakeTaskbarView.removeCallbacks(mFakeTaskbarViewCallback);
mFakeTaskbarViewCallback = null;
}
mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
}
@ -429,6 +436,38 @@ abstract class TutorialController implements BackGestureAttemptCallback,
mActionButton.setOnClickListener(this::onActionButtonClicked);
}
void hideFakeTaskbar(boolean animateToHotseat) {
if (!mTutorialFragment.isLargeScreen()) {
return;
}
if (mFakeTaskbarViewCallback != null) {
mFakeTaskbarView.removeCallbacks(mFakeTaskbarViewCallback);
}
if (animateToHotseat) {
mFakeTaskbarViewCallback = () ->
mFakeTaskbarView.animateDisappearanceToHotseat(mFakeHotseatView);
} else {
mFakeTaskbarViewCallback = mFakeTaskbarView::animateDisappearanceToBottom;
}
mFakeTaskbarView.post(mFakeTaskbarViewCallback);
}
void showFakeTaskbar(boolean animateFromHotseat) {
if (!mTutorialFragment.isLargeScreen()) {
return;
}
if (mFakeTaskbarViewCallback != null) {
mFakeTaskbarView.removeCallbacks(mFakeTaskbarViewCallback);
}
if (animateFromHotseat) {
mFakeTaskbarViewCallback = () ->
mFakeTaskbarView.animateAppearanceFromHotseat(mFakeHotseatView);
} else {
mFakeTaskbarViewCallback = mFakeTaskbarView::animateAppearanceFromBottom;
}
mFakeTaskbarView.post(mFakeTaskbarViewCallback);
}
void updateFakeAppTaskViewLayout(@LayoutRes int mockAppTaskLayoutResId) {
updateFakeViewLayout(mFakeTaskView, mockAppTaskLayoutResId);
}
@ -480,6 +519,8 @@ abstract class TutorialController implements BackGestureAttemptCallback,
mTutorialFragment.isLargeScreen()
? R.dimen.gesture_tutorial_foldable_feedback_margin_start_end
: R.dimen.gesture_tutorial_feedback_margin_start_end));
mFakeTaskbarView.setVisibility(mTutorialFragment.isLargeScreen() ? View.VISIBLE : GONE);
}
}