Created
May 30, 2016 21:48
-
-
Save rafakob/bda59626f0df0c12aaee6fcc41948f62 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.animation.ValueAnimator; | |
import android.graphics.Color; | |
import android.graphics.ColorMatrix; | |
import android.graphics.ColorMatrixColorFilter; | |
import android.support.design.widget.AppBarLayout; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.view.animation.AccelerateDecelerateInterpolator; | |
import android.view.animation.DecelerateInterpolator; | |
import android.widget.ImageView; | |
import com.rafakob.synomanager.R; | |
import com.rafakob.synomanager.utils.SizeUtils; | |
public class Animate { | |
/** | |
* Animate height of a ViewGroup object. | |
* | |
* @param target ViewGroup | |
* @return Builder | |
*/ | |
public static ValueAnimatorBuilder viewGroupHeight(ViewGroup target) { | |
return new ValueAnimatorBuilder<ViewGroup>(target) { | |
@Override | |
protected void onAnimationUpdate(ValueAnimator valueAnimator) { | |
ViewGroup.LayoutParams lp = target.getLayoutParams(); | |
lp.height = (int) valueAnimator.getAnimatedValue(); | |
target.setLayoutParams(lp); | |
} | |
}; | |
} | |
/** | |
* Animate height of a View object. | |
* | |
* @param target View | |
* @return Builder | |
*/ | |
public static ValueAnimatorBuilder viewHeight(View target) { | |
return new ValueAnimatorBuilder<View>(target) { | |
@Override | |
protected void onAnimationUpdate(ValueAnimator valueAnimator) { | |
ViewGroup.LayoutParams lp = target.getLayoutParams(); | |
lp.height = (int) valueAnimator.getAnimatedValue(); | |
target.setLayoutParams(lp); | |
} | |
}; | |
} | |
/** | |
* Animate toolbar expand | |
* | |
* @param target | |
* @return | |
*/ | |
public static ValueAnimatorBuilder expandAppBar(AppBarLayout target) { | |
int from = SizeUtils.getThemeDimension(target.getContext(), R.attr.actionBarSize); | |
int to = from + SizeUtils.getThemeDimension(target.getContext(), R.attr.tabLayoutHeight); | |
return Animate.viewGroupHeight(target).withIntValues(from, to).duration(200); | |
} | |
/** | |
* Animate toolbar collapse | |
* | |
* @param target | |
* @return | |
*/ | |
public static ValueAnimatorBuilder collapseAppBar(AppBarLayout target) { | |
int to = SizeUtils.getThemeDimension(target.getContext(), R.attr.actionBarSize); | |
int from = to + SizeUtils.getThemeDimension(target.getContext(), R.attr.tabLayoutHeight); | |
return Animate.viewGroupHeight(target).withIntValues(from, to).duration(200); | |
} | |
/** | |
* Fade in animation | |
* | |
* @param target | |
* @return | |
*/ | |
public static ValueAnimatorBuilder fadeIn(final View target) { | |
return fadeIn(target, 0); | |
} | |
public static ValueAnimatorBuilder fadeIn(final View target, float initialAlpha) { | |
ValueAnimatorBuilder builder = new ValueAnimatorBuilder<View>(target) { | |
@Override | |
protected void onAnimationUpdate(ValueAnimator valueAnimator) { | |
target.setAlpha((float) valueAnimator.getAnimatedValue()); | |
if (target.getParent() != null) { | |
((View) target.getParent()).postInvalidate(); | |
} | |
} | |
}; | |
target.setAlpha(initialAlpha); | |
if (initialAlpha == 0 && target.getVisibility() != View.VISIBLE) { | |
target.setVisibility(View.VISIBLE); | |
} | |
return builder.withFloatValues(target.getAlpha(), 1) | |
.duration((int) (200 * (1 - target.getAlpha()))) | |
.interpolator(new DecelerateInterpolator()); | |
} | |
/** | |
* Fade out animation | |
* | |
* @param target | |
* @return | |
*/ | |
public static ValueAnimatorBuilder fadeOut(final View target) { | |
ValueAnimatorBuilder builder = new ValueAnimatorBuilder<View>(target) { | |
@Override | |
protected void onAnimationUpdate(ValueAnimator valueAnimator) { | |
target.setAlpha((Float) valueAnimator.getAnimatedValue()); | |
if (target.getParent() != null) { | |
((View) target.getParent()).postInvalidate(); | |
} | |
} | |
}; | |
return builder.withFloatValues(target.getAlpha(), 0) | |
.duration((int) (200 * target.getAlpha())) | |
.interpolator(new DecelerateInterpolator()); | |
} | |
/** | |
* Pop in animation | |
* | |
* @param target | |
* @return | |
*/ | |
public static ValueAnimatorBuilder popIn(final View target) { | |
return popIn(target, 0); | |
} | |
public static ValueAnimatorBuilder popIn(final View target, float initialAlpha) { | |
ValueAnimatorBuilder builder = new ValueAnimatorBuilder<View>(target) { | |
@Override | |
protected void onAnimationUpdate(ValueAnimator valueAnimator) { | |
target.setAlpha((Float) valueAnimator.getAnimatedValue()); | |
target.setScaleX((Float) valueAnimator.getAnimatedValue()); | |
target.setScaleY((Float) valueAnimator.getAnimatedValue()); | |
if (target.getParent() != null) { | |
((View) target.getParent()).postInvalidate(); | |
} | |
} | |
}; | |
target.setAlpha(initialAlpha); | |
if (initialAlpha == 0 && target.getVisibility() != View.VISIBLE) { | |
target.setVisibility(View.VISIBLE); | |
} | |
return builder.withFloatValues(target.getAlpha(), 1) | |
.duration((int) (200 * (1 - target.getAlpha()))) | |
.interpolator(new DecelerateInterpolator()); | |
} | |
/** | |
* Pop out animation | |
* | |
* @param target | |
* @return | |
*/ | |
public static ValueAnimatorBuilder popOut(final View target) { | |
ValueAnimatorBuilder builder = new ValueAnimatorBuilder<View>(target) { | |
@Override | |
protected void onAnimationUpdate(ValueAnimator valueAnimator) { | |
target.setAlpha((Float) valueAnimator.getAnimatedValue()); | |
target.setScaleX((Float) valueAnimator.getAnimatedValue()); | |
target.setScaleY((Float) valueAnimator.getAnimatedValue()); | |
if (target.getParent() != null) { | |
((View) target.getParent()).postInvalidate(); | |
} | |
} | |
}; | |
return builder.withFloatValues(target.getAlpha(), 0) | |
.duration((int) (200 * target.getAlpha())) | |
.interpolator(new DecelerateInterpolator()); | |
} | |
/** | |
* Fly in animation | |
* | |
* @param target | |
* @return | |
*/ | |
public static ValueAnimatorBuilder flyIn(final View target) { | |
return flyIn(target, 0); | |
} | |
public static ValueAnimatorBuilder flyIn(final View target, float initialAlpha) { | |
ValueAnimatorBuilder builder = new ValueAnimatorBuilder<View>(target) { | |
@Override | |
protected void onAnimationUpdate(ValueAnimator valueAnimator) { | |
target.setAlpha((Float) valueAnimator.getAnimatedValue()); | |
target.setTranslationY(Math.min(target.getHeight() / 2, target.getResources().getDimension(R.dimen.carbon_1dip) * 50.0f) * (1 - (Float) valueAnimator.getAnimatedValue())); | |
if (target.getParent() != null) { | |
((View) target.getParent()).postInvalidate(); | |
} | |
} | |
}; | |
target.setAlpha(initialAlpha); | |
if (initialAlpha == 0 && target.getVisibility() != View.VISIBLE) { | |
target.setVisibility(View.VISIBLE); | |
} | |
return builder.withFloatValues(target.getAlpha(), 1) | |
.duration((int) (200 * (1 - target.getAlpha()))) | |
.interpolator(new DecelerateInterpolator()); | |
} | |
/** | |
* Fly out animation | |
* | |
* @param target | |
* @return | |
*/ | |
public static ValueAnimatorBuilder flyOut(final View target) { | |
ValueAnimatorBuilder builder = new ValueAnimatorBuilder<View>(target) { | |
@Override | |
protected void onAnimationUpdate(ValueAnimator valueAnimator) { | |
target.setAlpha((Float) valueAnimator.getAnimatedValue()); | |
target.setTranslationY(Math.min(target.getHeight() / 2, target.getResources().getDimension(R.dimen.carbon_1dip) * 50.0f) * (1 - (Float) valueAnimator.getAnimatedValue())); | |
if (target.getParent() != null) { | |
((View) target.getParent()).postInvalidate(); | |
} | |
} | |
}; | |
return builder.withFloatValues(target.getAlpha(), 0) | |
.duration((int) (200 * target.getAlpha())) | |
.interpolator(new DecelerateInterpolator()); | |
} | |
/** | |
* BrightnessSaturationFadeIn | |
* | |
* @param target | |
* @return | |
*/ | |
public static ValueAnimatorBuilder brightnessSaturationFadeIn(final ImageView target) { | |
final AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator(); | |
ValueAnimatorBuilder builder = new ValueAnimatorBuilder<ImageView>(target) { | |
ColorMatrix saturationMatrix = new ColorMatrix(); | |
ColorMatrix brightnessMatrix = new ColorMatrix(); | |
@Override | |
public void onAnimationUpdate(ValueAnimator valueAnimator) { | |
float fraction = animator.getAnimatedFraction(); | |
saturationMatrix.setSaturation((Float) animator.getAnimatedValue()); | |
float scale = 2 - interpolator.getInterpolation(Math.min(fraction * 4 / 3, 1)); | |
brightnessMatrix.setScale(scale, scale, scale, interpolator.getInterpolation(Math.min(fraction * 2, 1))); | |
saturationMatrix.preConcat(brightnessMatrix); | |
target.setColorFilter(new ColorMatrixColorFilter(saturationMatrix)); | |
if (target.getParent() != null) { | |
((View) target.getParent()).postInvalidate(); | |
} | |
} | |
}; | |
return builder.withFloatValues(0, 1) | |
.duration(800) | |
.interpolator(interpolator); | |
} | |
/** | |
* BrightnessSaturationFadeOut | |
* | |
* @param target | |
* @return | |
*/ | |
public static ValueAnimatorBuilder brightnessSaturationFadeOut(final ImageView target) { | |
final AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator(); | |
ValueAnimatorBuilder builder = new ValueAnimatorBuilder<ImageView>(target) { | |
ColorMatrix saturationMatrix = new ColorMatrix(); | |
ColorMatrix brightnessMatrix = new ColorMatrix(); | |
@Override | |
public void onAnimationUpdate(ValueAnimator valueAnimator) { | |
float fraction = animator.getAnimatedFraction(); | |
saturationMatrix.setSaturation((Float) animator.getAnimatedValue()); | |
float scale = 2 - interpolator.getInterpolation(Math.min((1 - fraction) * 4 / 3, 1)); | |
brightnessMatrix.setScale(scale, scale, scale, interpolator.getInterpolation(Math.min((1 - fraction) * 2, 1))); | |
saturationMatrix.preConcat(brightnessMatrix); | |
target.setColorFilter(new ColorMatrixColorFilter(saturationMatrix)); | |
if (target.getParent() != null) { | |
((View) target.getParent()).postInvalidate(); | |
} | |
} | |
}; | |
return builder.withFloatValues(1, 0) | |
.duration(800) | |
.interpolator(interpolator); | |
} | |
public static float lerp(float interpolation, float val1, float val2) { | |
return val1 * (1 - interpolation) + val2 * interpolation; | |
} | |
public static int lerpColor(float interpolation, int val1, int val2) { | |
int a = (int) lerp(interpolation, val1 >> 24, val2 >> 24); | |
int r = (int) lerp(interpolation, (val1 >> 16) & 0xff, (val2 >> 16) & 0xff); | |
int g = (int) lerp(interpolation, (val1 >> 8) & 0xff, (val2 >> 8) & 0xff); | |
int b = (int) lerp(interpolation, val1 & 0xff, val2 & 0xff); | |
return Color.argb(a, r, g, b); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.content.res.Resources; | |
import android.content.res.TypedArray; | |
import android.graphics.Point; | |
import android.support.annotation.AttrRes; | |
import android.support.annotation.NonNull; | |
import android.view.Display; | |
import android.view.WindowManager; | |
public class SizeUtils { | |
private static int screenWidth = 0; | |
private static int screenHeight = 0; | |
public static int dpToPx(int dp) { | |
return (int) (dp * Resources.getSystem().getDisplayMetrics().density); | |
} | |
public static int getScreenHeight(Context c) { | |
if (screenHeight == 0) { | |
WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE); | |
Display display = wm.getDefaultDisplay(); | |
Point size = new Point(); | |
display.getSize(size); | |
screenHeight = size.y; | |
} | |
return screenHeight; | |
} | |
public static int getScreenWidth(Context c) { | |
if (screenWidth == 0) { | |
WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE); | |
Display display = wm.getDefaultDisplay(); | |
Point size = new Point(); | |
display.getSize(size); | |
screenWidth = size.x; | |
} | |
return screenWidth; | |
} | |
public static int getThemeDimension(@NonNull final Context context, @AttrRes final int attr) { | |
TypedArray a = null; | |
try { | |
a = context.getTheme().obtainStyledAttributes(new int[]{attr}); | |
return a.getDimensionPixelSize(0, 0); | |
} finally { | |
if (a != null) { | |
a.recycle(); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.animation.Animator; | |
import android.animation.ValueAnimator; | |
import android.os.Build; | |
import android.view.animation.Interpolator; | |
public abstract class ValueAnimatorBuilder<T> { | |
protected ValueAnimator animator; | |
protected T target; | |
protected int[] valuesInt; | |
protected int[] valuesArgb; | |
protected float[] valuesFloat; | |
protected int from; | |
protected int to; | |
protected int duration = 200; | |
protected int delay = 0; | |
protected Interpolator interpolator; | |
protected Animator.AnimatorListener animatorListener; | |
public ValueAnimatorBuilder(T target) { | |
this.target = target; | |
} | |
public ValueAnimatorBuilder withIntValues(int... valuesInt) { | |
this.valuesInt = valuesInt; | |
return this; | |
} | |
public ValueAnimatorBuilder withArgbValues(int... valuesArgb) { | |
this.valuesArgb = valuesArgb; | |
return this; | |
} | |
public ValueAnimatorBuilder withFloatValues(float... valuesFloat) { | |
this.valuesFloat = valuesFloat; | |
return this; | |
} | |
public ValueAnimatorBuilder duration(int duration) { | |
this.duration = duration; | |
return this; | |
} | |
public ValueAnimatorBuilder delay(int delay) { | |
this.delay = delay; | |
return this; | |
} | |
public ValueAnimatorBuilder interpolator(Interpolator interpolator) { | |
this.interpolator = interpolator; | |
return this; | |
} | |
public ValueAnimatorBuilder listener(Animator.AnimatorListener animatorListener) { | |
this.animatorListener = animatorListener; | |
return this; | |
} | |
public ValueAnimator build() { | |
/* Create */ | |
if (valuesInt != null && valuesInt.length > 0) { | |
animator = ValueAnimator.ofInt(valuesInt); | |
} | |
if (valuesArgb != null && valuesArgb.length > 0) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
animator = ValueAnimator.ofArgb(valuesArgb); | |
} | |
} | |
if (valuesFloat != null && valuesFloat.length > 0) { | |
animator = ValueAnimator.ofFloat(valuesFloat); | |
} | |
if (animator == null) { | |
throw new NullPointerException("ValueAnimatorBuilder - animator object has not been initialized!"); | |
} | |
/* Target */ | |
animator.setTarget(target); | |
/* Duration */ | |
animator.setDuration(duration); | |
/* Delay */ | |
animator.setStartDelay(delay); | |
/* Interpolator */ | |
if (interpolator != null) { | |
animator.setInterpolator(interpolator); | |
} | |
/* Animation OnPositiveListener */ | |
if (animatorListener != null) { | |
animator.addListener(animatorListener); | |
} | |
/* Update OnPositiveListener */ | |
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | |
@Override | |
public void onAnimationUpdate(ValueAnimator valueAnimator) { | |
ValueAnimatorBuilder.this.onAnimationUpdate(valueAnimator); | |
} | |
}); | |
/* Start */ | |
animator.start(); | |
return animator; | |
} | |
public void start() { | |
if (animator == null) { | |
build().start(); | |
} else { | |
animator.start(); | |
} | |
} | |
protected abstract void onAnimationUpdate(ValueAnimator valueAnimator); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment