Merge "Update full screen animation for handhelds to accurately represent screensize/shape" into udc-dev
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user