Merge "Make sure all transition components run on the same thread" into ub-launcher3-burnaby
This commit is contained in:
@@ -26,6 +26,9 @@ import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
import android.view.ViewTreeObserver;
|
||||
|
||||
import com.android.launcher3.util.UiThreadCircularReveal;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
@@ -130,13 +133,11 @@ public class LauncherAnimUtils {
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Animator createCircularReveal(View view, int centerX,
|
||||
public static ValueAnimator createCircularReveal(View view, int centerX,
|
||||
int centerY, float startRadius, float endRadius) {
|
||||
Animator anim = ViewAnimationUtils.createCircularReveal(view, centerX,
|
||||
ValueAnimator anim = UiThreadCircularReveal.createCircularReveal(view, centerX,
|
||||
centerY, startRadius, endRadius);
|
||||
if (anim instanceof ValueAnimator) {
|
||||
new FirstFrameAnimatorHelper((ValueAnimator) anim, view);
|
||||
}
|
||||
new FirstFrameAnimatorHelper(anim, view);
|
||||
return anim;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,14 @@ import android.annotation.SuppressLint;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
|
||||
import com.android.launcher3.allapps.AllAppsContainerView;
|
||||
import com.android.launcher3.util.UiThreadCircularReveal;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
import com.android.launcher3.widget.WidgetsContainerView;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
@@ -320,7 +322,7 @@ public class LauncherStateTransitionAnimation {
|
||||
float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
|
||||
AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
|
||||
revealView, allAppsButtonView);
|
||||
Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,
|
||||
Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
|
||||
height / 2, startRadius, revealRadius);
|
||||
reveal.setDuration(revealDuration);
|
||||
reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
|
||||
@@ -587,14 +589,14 @@ public class LauncherStateTransitionAnimation {
|
||||
TimeInterpolator decelerateInterpolator = material ?
|
||||
new LogDecelerateInterpolator(100, 0) :
|
||||
new DecelerateInterpolator(1f);
|
||||
ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",
|
||||
ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
|
||||
0, revealViewToYDrift);
|
||||
panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
|
||||
panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
|
||||
panelDriftY.setInterpolator(decelerateInterpolator);
|
||||
mStateAnimation.play(panelDriftY);
|
||||
|
||||
ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",
|
||||
ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
|
||||
0, revealViewToXDrift);
|
||||
panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
|
||||
panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
|
||||
@@ -605,7 +607,7 @@ public class LauncherStateTransitionAnimation {
|
||||
final float revealViewToAlpha = !material ? 0f :
|
||||
pCb.getMaterialRevealViewFinalAlpha(revealView);
|
||||
if (revealViewToAlpha != 1f) {
|
||||
ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",
|
||||
ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
|
||||
1f, revealViewToAlpha);
|
||||
panelAlpha.setDuration(material ? revealDuration : 150);
|
||||
panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
|
||||
@@ -617,7 +619,7 @@ public class LauncherStateTransitionAnimation {
|
||||
layerViews.put(contentView, BUILD_AND_SET_LAYER);
|
||||
|
||||
// Create the individual animators
|
||||
ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(contentView, "translationY",
|
||||
ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
|
||||
0, revealViewToYDrift);
|
||||
contentView.setTranslationY(0);
|
||||
pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
|
||||
@@ -626,7 +628,7 @@ public class LauncherStateTransitionAnimation {
|
||||
mStateAnimation.play(pageDrift);
|
||||
|
||||
contentView.setAlpha(1f);
|
||||
ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(contentView, "alpha", 1f, 0f);
|
||||
ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
|
||||
itemsAlpha.setDuration(100);
|
||||
itemsAlpha.setInterpolator(decelerateInterpolator);
|
||||
mStateAnimation.play(itemsAlpha);
|
||||
@@ -636,9 +638,8 @@ public class LauncherStateTransitionAnimation {
|
||||
float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
|
||||
AnimatorListenerAdapter listener =
|
||||
pCb.getMaterialRevealViewAnimatorListener(revealView, allAppsButtonView);
|
||||
Animator reveal =
|
||||
LauncherAnimUtils.createCircularReveal(revealView, width / 2,
|
||||
height / 2, revealRadius, finalRadius);
|
||||
Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
|
||||
height / 2, revealRadius, finalRadius);
|
||||
reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
|
||||
reveal.setDuration(revealDuration);
|
||||
reveal.setStartDelay(itemsAlphaStagger);
|
||||
@@ -782,4 +783,4 @@ public class LauncherStateTransitionAnimation {
|
||||
mStateAnimation = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +127,11 @@ public final class Utilities {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
||||
}
|
||||
|
||||
public static boolean isLmpMR1OrAbove() {
|
||||
// TODO(adamcohen): update to Build.VERSION_CODES.LOLLIPOP_MR1 once building against 22;
|
||||
return Build.VERSION.SDK_INT >= 22;
|
||||
}
|
||||
|
||||
static Bitmap createIconBitmap(Cursor c, int iconIndex, Context context) {
|
||||
byte[] data = c.getBlob(iconIndex);
|
||||
try {
|
||||
@@ -588,7 +593,6 @@ public final class Utilities {
|
||||
}
|
||||
|
||||
public static final Comparator<ItemInfo> RANK_COMPARATOR = new Comparator<ItemInfo>() {
|
||||
|
||||
@Override
|
||||
public int compare(ItemInfo lhs, ItemInfo rhs) {
|
||||
return lhs.rank - rhs.rank;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.android.launcher3.util;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.ViewOutlineProvider;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public class RevealOutlineProvider extends ViewOutlineProvider {
|
||||
|
||||
private int mCenterX;
|
||||
private int mCenterY;
|
||||
private float mRadius0;
|
||||
private float mRadius1;
|
||||
private int mCurrentRadius;
|
||||
|
||||
private final Rect mOval;
|
||||
|
||||
/**
|
||||
* @param x reveal center x
|
||||
* @param y reveal center y
|
||||
* @param r0 initial radius
|
||||
* @param r1 final radius
|
||||
*/
|
||||
public RevealOutlineProvider(int x, int y, float r0, float r1) {
|
||||
mCenterX = x;
|
||||
mCenterY = y;
|
||||
mRadius0 = r0;
|
||||
mRadius1 = r1;
|
||||
|
||||
mOval = new Rect();
|
||||
}
|
||||
|
||||
public void setProgress(float progress) {
|
||||
mCurrentRadius = (int) ((1 - progress) * mRadius0 + progress * mRadius1);
|
||||
|
||||
mOval.left = mCenterX - mCurrentRadius;
|
||||
mOval.top = mCenterY - mCurrentRadius;
|
||||
mOval.right = mCenterX + mCurrentRadius;
|
||||
mOval.bottom = mCenterY + mCurrentRadius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getOutline(View v, Outline outline) {
|
||||
outline.setRoundRect(mOval, mCurrentRadius);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.android.launcher3.util;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.ViewOutlineProvider;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public class UiThreadCircularReveal {
|
||||
|
||||
public static ValueAnimator createCircularReveal(View v, int x, int y, float r0, float r1) {
|
||||
ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
|
||||
|
||||
final View revealView = v;
|
||||
final RevealOutlineProvider outlineProvider = new RevealOutlineProvider(x, y, r0, r1);
|
||||
final ViewOutlineProvider originalProvider = revealView.getOutlineProvider();
|
||||
final float elevation = v.getElevation();
|
||||
|
||||
va.addListener(new AnimatorListenerAdapter() {
|
||||
public void onAnimationStart(Animator animation) {
|
||||
revealView.setOutlineProvider(outlineProvider);
|
||||
revealView.setClipToOutline(true);
|
||||
revealView.setTranslationZ(-elevation);
|
||||
}
|
||||
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
revealView.setOutlineProvider(originalProvider);
|
||||
revealView.setClipToOutline(false);
|
||||
revealView.setTranslationZ(0);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
va.addUpdateListener(new AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator arg0) {
|
||||
float progress = arg0.getAnimatedFraction();
|
||||
outlineProvider.setProgress(progress);
|
||||
if (Utilities.isLmpMR1OrAbove()) {
|
||||
revealView.invalidateOutline();
|
||||
} else {
|
||||
// On L, a bug requires calling a full view invalidate.
|
||||
revealView.invalidate();
|
||||
}
|
||||
}
|
||||
});
|
||||
return va;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user