Merge "Update full screen animation for handhelds to accurately represent screensize/shape" into udc-dev

This commit is contained in:
Randy Pfohl
2023-04-13 15:26:00 +00:00
committed by Android (Google) Code Review
2 changed files with 92 additions and 27 deletions
@@ -42,8 +42,6 @@
android:id="@+id/gesture_tutorial_fake_previous_task_view" android:id="@+id/gesture_tutorial_fake_previous_task_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleX="0.98"
android:scaleY="0.98"
android:visibility="invisible"> android:visibility="invisible">
<View <View
@@ -15,6 +15,10 @@
*/ */
package com.android.quickstep.interaction; package com.android.quickstep.interaction;
import static com.android.launcher3.QuickstepTransitionManager.ANIMATION_NAV_FADE_OUT_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.NAV_FADE_OUT_INTERPOLATOR;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL; import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
import android.animation.Animator; import android.animation.Animator;
@@ -29,6 +33,8 @@ import android.graphics.Outline;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.Display;
import android.view.RoundedCorner;
import android.view.View; import android.view.View;
import android.view.ViewOutlineProvider; import android.view.ViewOutlineProvider;
import android.view.animation.ScaleAnimation; import android.view.animation.ScaleAnimation;
@@ -40,8 +46,12 @@ import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintLayout;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.Interpolators;
import com.android.quickstep.util.MultiValueUpdateListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
/** /**
* Helper View for the gesture tutorial mock previous app task view. * Helper View for the gesture tutorial mock previous app task view.
@@ -51,6 +61,8 @@ import java.util.ArrayList;
*/ */
public class AnimatedTaskView extends ConstraintLayout { public class AnimatedTaskView extends ConstraintLayout {
private static final long ANIMATE_TO_FULL_SCREEN_DURATION = 300;
private View mFullTaskView; private View mFullTaskView;
private View mTopTaskView; private View mTopTaskView;
private View mBottomTaskView; private View mBottomTaskView;
@@ -92,33 +104,86 @@ public class AnimatedTaskView extends ConstraintLayout {
setToSingleRowLayout(false); setToSingleRowLayout(false);
} }
void animateToFillScreen(@Nullable Runnable onAnimationEndCallback) { void animateToFillScreen(@Nullable Runnable onAnimationEndCallback) {
if (mTaskViewOutlineProvider == null) {
// This is an illegal state.
return;
}
// calculate start and end corner radius
Outline startOutline = new Outline();
mTaskViewOutlineProvider.getOutline(this, startOutline);
Rect outlineStartRect = new Rect();
startOutline.getRect(outlineStartRect);
float outlineStartRadius = startOutline.getRadius();
final Display display = mContext.getDisplay();;
RoundedCorner corner = display.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT);
float outlineEndRadius = corner.getRadius();
// create animation
AnimatorSet set = new AnimatorSet(); AnimatorSet set = new AnimatorSet();
ArrayList<Animator> animations = new ArrayList<>(); ArrayList<Animator> animations = new ArrayList<>();
// center view // center view
animations.add(ObjectAnimator.ofFloat(this, TRANSLATION_X, 0)); animations.add(ObjectAnimator.ofFloat(this, TRANSLATION_X, 0));
// calculate full screen scaling, scale should be 1:1 for x and y // retrieve start animation matrix to scale off of
Matrix matrix = getAnimationMatrix(); Matrix matrix = getAnimationMatrix();
if (matrix == null) {
// This is an illegal state.
return;
}
float[] matrixValues = new float[9]; float[] matrixValues = new float[9];
matrix.getValues(matrixValues); matrix.getValues(matrixValues);
float scaleX = matrixValues[Matrix.MSCALE_X]; float[] newValues = matrixValues.clone();
float scaleToFullScreen = 1 / scaleX;
// scale view to full screen ValueAnimator transformAnimation = ValueAnimator.ofFloat(0, 1);
ValueAnimator scale = ValueAnimator.ofFloat(1f, scaleToFullScreen);
scale.addUpdateListener(animation -> {
float value = (float) animation.getAnimatedValue();
mFullTaskView.setScaleX(value);
mFullTaskView.setScaleY(value);
});
animations.add(scale); MultiValueUpdateListener listener = new MultiValueUpdateListener() {
Matrix currentMatrix = new Matrix();
FloatProp mOutlineRadius = new FloatProp(outlineStartRadius, outlineEndRadius, 0,
ANIMATE_TO_FULL_SCREEN_DURATION, LINEAR);
FloatProp mTransX = new FloatProp(matrixValues[Matrix.MTRANS_X], 0f, 0,
ANIMATE_TO_FULL_SCREEN_DURATION, LINEAR);
FloatProp mTransY = new FloatProp(matrixValues[Matrix.MTRANS_Y], 0f, 0,
ANIMATE_TO_FULL_SCREEN_DURATION, LINEAR);
FloatProp mScaleX = new FloatProp(matrixValues[Matrix.MSCALE_X], 1f, 0,
ANIMATE_TO_FULL_SCREEN_DURATION, LINEAR);
FloatProp mScaleY = new FloatProp(matrixValues[Matrix.MSCALE_Y], 1f, 0,
ANIMATE_TO_FULL_SCREEN_DURATION, LINEAR);
@Override
public void onUpdate(float percent, boolean initOnly) {
// scale corner radius to match display radius
mTaskViewAnimatedRadius = mOutlineRadius.value;
mFullTaskView.invalidateOutline();
// translate to center, ends at translation x:0, y:0
newValues[Matrix.MTRANS_X] = mTransX.value;
newValues[Matrix.MTRANS_Y] = mTransY.value;
// scale to full size, ends at scale 1
newValues[Matrix.MSCALE_X] = mScaleX.value;
newValues[Matrix.MSCALE_Y] = mScaleY.value;
// create and set new animation matrix
currentMatrix.setValues(newValues);
setAnimationMatrix(currentMatrix);
}
};
transformAnimation.addUpdateListener(listener);
animations.add(transformAnimation);
set.playSequentially(animations); set.playSequentially(animations);
set.addListener(new AnimatorListenerAdapter() { set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
addAnimatedOutlineProvider(mFullTaskView, outlineStartRect, outlineStartRadius);
}
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation); super.onAnimationEnd(animation);
@@ -127,7 +192,6 @@ public class AnimatedTaskView extends ConstraintLayout {
} }
} }
}); });
set.start(); set.start();
} }
@@ -158,17 +222,7 @@ public class AnimatedTaskView extends ConstraintLayout {
@Override @Override
public void onAnimationStart(Animator animation) { public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation); super.onAnimationStart(animation);
addAnimatedOutlineProvider(mFullTaskView, outlineStartRect, outlineStartRadius);
mTaskViewAnimatedRect.set(outlineStartRect);
mTaskViewAnimatedRadius = outlineStartRadius;
mFullTaskView.setClipToOutline(true);
mFullTaskView.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(mTaskViewAnimatedRect, mTaskViewAnimatedRadius);
}
});
} }
@Override @Override
@@ -247,4 +301,17 @@ public class AnimatedTaskView extends ConstraintLayout {
mTaskViewOutlineProvider = provider; mTaskViewOutlineProvider = provider;
mFullTaskView.setOutlineProvider(mTaskViewOutlineProvider); mFullTaskView.setOutlineProvider(mTaskViewOutlineProvider);
} }
private void addAnimatedOutlineProvider(View view,
Rect outlineStartRect, float outlineStartRadius){
mTaskViewAnimatedRect.set(outlineStartRect);
mTaskViewAnimatedRadius = outlineStartRadius;
view.setClipToOutline(true);
view.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(mTaskViewAnimatedRect, mTaskViewAnimatedRadius);
}
});
}
} }