1 package com.android.launcher3.util; 2 3 import android.animation.Animator; 4 import android.animation.AnimatorListenerAdapter; 5 import android.animation.ValueAnimator; 6 import android.animation.ValueAnimator.AnimatorUpdateListener; 7 import android.annotation.TargetApi; 8 import android.os.Build; 9 import android.view.View; 10 import android.view.ViewOutlineProvider; 11 12 import com.android.launcher3.Utilities; 13 14 @TargetApi(Build.VERSION_CODES.LOLLIPOP) 15 public class UiThreadCircularReveal { 16 17 public static ValueAnimator createCircularReveal(View v, int x, int y, float r0, float r1) { 18 return createCircularReveal(v, x, y, r0, r1, ViewOutlineProvider.BACKGROUND); 19 } 20 21 public static ValueAnimator createCircularReveal(View v, int x, int y, float r0, float r1, 22 final ViewOutlineProvider originalProvider) { 23 ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); 24 25 final View revealView = v; 26 final RevealOutlineProvider outlineProvider = new RevealOutlineProvider(x, y, r0, r1); 27 final float elevation = v.getElevation(); 28 29 va.addListener(new AnimatorListenerAdapter() { 30 public void onAnimationStart(Animator animation) { 31 revealView.setOutlineProvider(outlineProvider); 32 revealView.setClipToOutline(true); 33 revealView.setTranslationZ(-elevation); 34 } 35 36 public void onAnimationEnd(Animator animation) { 37 revealView.setOutlineProvider(originalProvider); 38 revealView.setClipToOutline(false); 39 revealView.setTranslationZ(0); 40 } 41 42 }); 43 44 va.addUpdateListener(new AnimatorUpdateListener() { 45 @Override 46 public void onAnimationUpdate(ValueAnimator arg0) { 47 float progress = arg0.getAnimatedFraction(); 48 outlineProvider.setProgress(progress); 49 revealView.invalidateOutline(); 50 if (!Utilities.ATLEAST_LOLLIPOP_MR1) { 51 revealView.invalidate(); 52 } 53 } 54 }); 55 return va; 56 } 57 } 58