Merge "Add mock animated taskbar to gesture nav tutorial for foldable devices." into sc-v2-dev
This commit is contained in:
commit
3edb8de094
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue