Last active
February 27, 2019 21:26
-
-
Save Ferfalk/1c9687be9f4fba3cf6ecc79b1871fdf5 to your computer and use it in GitHub Desktop.
Android SimpleAnimationUtils
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.AnimatorListenerAdapter; | |
import android.animation.ObjectAnimator; | |
import android.animation.ValueAnimator; | |
import android.graphics.Point; | |
import android.os.Build; | |
import android.support.annotation.NonNull; | |
import android.support.annotation.Nullable; | |
import android.support.annotation.RequiresApi; | |
import android.support.v4.view.animation.FastOutSlowInInterpolator; | |
import android.view.View; | |
import android.view.ViewAnimationUtils; | |
import android.view.animation.Interpolator; | |
import java.util.ArrayList; | |
import java.util.List; | |
/** | |
* @author Fernando A. H. Falkiewicz | |
*/ | |
public class SimpleAnimationUtils { | |
public static final int ANIMATION_DURATION_DEFAULT = 250; | |
private SimpleAnimationUtils() { | |
} | |
public static Animator revealOrFadeIn(@NonNull final View view) { | |
return revealOrFadeIn(view, ANIMATION_DURATION_DEFAULT); | |
} | |
public static Animator revealOrFadeIn(@NonNull final View view, int duration) { | |
return revealOrFadeIn(view, duration, null, null); | |
} | |
public static Animator revealOrFadeIn(@NonNull final View view, int duration, @Nullable final AnimationListener listener) { | |
return revealOrFadeIn(view, duration, listener, null); | |
} | |
public static Animator revealOrFadeIn(@NonNull final View view, int duration, @Nullable Point center) { | |
return revealOrFadeIn(view, duration, null, center); | |
} | |
public static Animator revealOrFadeIn(@NonNull final View view, @Nullable final AnimationListener listener) { | |
return revealOrFadeIn(view, ANIMATION_DURATION_DEFAULT, listener, null); | |
} | |
public static Animator revealOrFadeIn(@NonNull final View view, @Nullable Point center) { | |
return revealOrFadeIn(view, ANIMATION_DURATION_DEFAULT, null, center); | |
} | |
public static Animator revealOrFadeIn(@NonNull final View view, @Nullable final AnimationListener listener, @Nullable Point center) { | |
return revealOrFadeIn(view, ANIMATION_DURATION_DEFAULT, listener, center); | |
} | |
public static Animator revealOrFadeIn(@NonNull final View view, int duration, @Nullable final AnimationListener listener, @Nullable Point center) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
return reveal(view, duration, listener, center); | |
} else { | |
return fadeIn(view, duration, listener); | |
} | |
} | |
public static Animator hideOrFadeOut(@NonNull final View view, int duration) { | |
return hideOrFadeOut(view, duration, null, null); | |
} | |
public static Animator hideOrFadeOut(@NonNull final View view, int duration, @Nullable final AnimationListener listener) { | |
return hideOrFadeOut(view, duration, listener, null); | |
} | |
public static Animator hideOrFadeOut(@NonNull final View view, int duration, @Nullable Point center) { | |
return hideOrFadeOut(view, duration, null, center); | |
} | |
public static Animator hideOrFadeOut(@NonNull final View view) { | |
return hideOrFadeOut(view, ANIMATION_DURATION_DEFAULT); | |
} | |
public static Animator hideOrFadeOut(@NonNull final View view, @Nullable final AnimationListener listener) { | |
return hideOrFadeOut(view, ANIMATION_DURATION_DEFAULT, listener, null); | |
} | |
public static Animator hideOrFadeOut(@NonNull final View view, @Nullable Point center) { | |
return hideOrFadeOut(view, ANIMATION_DURATION_DEFAULT, null, center); | |
} | |
public static Animator hideOrFadeOut(@NonNull final View view, @Nullable final AnimationListener listener, @Nullable Point center) { | |
return hideOrFadeOut(view, ANIMATION_DURATION_DEFAULT, listener, center); | |
} | |
public static Animator hideOrFadeOut(@NonNull final View view, int duration, @Nullable final AnimationListener listener, @Nullable Point center) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
return hide(view, duration, listener, center); | |
} else { | |
return fadeOut(view, duration, listener); | |
} | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator reveal(@NonNull final View view, int duration) { | |
return reveal(view, duration, null, null); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator reveal(@NonNull final View view, int duration, @Nullable Point center) { | |
return reveal(view, duration, null, center); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator reveal(@NonNull final View view, int duration, @Nullable final AnimationListener listener) { | |
return reveal(view, duration, listener, null); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator reveal(@NonNull final View view) { | |
return reveal(view, ANIMATION_DURATION_DEFAULT); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator reveal(@NonNull final View view, @Nullable final AnimationListener listener) { | |
return reveal(view, ANIMATION_DURATION_DEFAULT, listener, null); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator reveal(@NonNull final View view, @Nullable Point center) { | |
return reveal(view, ANIMATION_DURATION_DEFAULT, null, center); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator reveal(@NonNull final View view, @Nullable final AnimationListener listener, @Nullable Point center) { | |
return reveal(view, ANIMATION_DURATION_DEFAULT, listener, center); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator reveal(@NonNull final View view, int duration, @Nullable final AnimationListener listener, @Nullable Point center) { | |
if (center == null) { | |
center = getDefaultCenter(view); | |
} | |
Animator anim = ViewAnimationUtils.createCircularReveal(view, center.x, center.y, 0, getRevealRadius(center, view)); | |
anim.addListener(new DefaultActionAnimationListener(view, listener) { | |
@Override | |
void defaultOnAnimationStart(@NonNull View view) { | |
view.setVisibility(View.VISIBLE); | |
} | |
}); | |
anim.setDuration(duration); | |
anim.setInterpolator(getDefaultInterpolator()); | |
return anim; | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator hide(@NonNull final View view, int duration) { | |
return hide(view, duration, null, null); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator hide(@NonNull final View view, int duration, @Nullable Point center) { | |
return hide(view, duration, null, center); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator hide(@NonNull final View view, int duration, @Nullable final AnimationListener listener) { | |
return hide(view, duration, listener, null); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator hide(@NonNull final View view) { | |
return hide(view, ANIMATION_DURATION_DEFAULT); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator hide(@NonNull final View view, @Nullable final AnimationListener listener) { | |
return hide(view, ANIMATION_DURATION_DEFAULT, listener, null); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator hide(@NonNull final View view, @Nullable Point center) { | |
return hide(view, ANIMATION_DURATION_DEFAULT, null, center); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator hide(@NonNull final View view, @Nullable final AnimationListener listener, @Nullable Point center) { | |
return hide(view, ANIMATION_DURATION_DEFAULT, listener, center); | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
public static Animator hide(@NonNull final View view, int duration, @Nullable final AnimationListener listener, @Nullable Point center) { | |
if (center == null) { | |
center = getDefaultCenter(view); | |
} | |
Animator anim = ViewAnimationUtils.createCircularReveal(view, center.x, center.y, getRevealRadius(center, view), 0); | |
anim.addListener(new DefaultActionAnimationListener(view, listener) { | |
@Override | |
void defaultOnAnimationEnd(@NonNull View view) { | |
view.setVisibility(View.GONE); | |
} | |
}); | |
anim.setDuration(duration); | |
anim.setInterpolator(getDefaultInterpolator()); | |
return anim; | |
} | |
@NonNull | |
public static Point getDefaultCenter(@Nullable View view) { | |
if (view == null) | |
return new Point(); | |
int revealX = (int) (view.getX() + view.getWidth() / 2); | |
int revealY = (int) (view.getY() + view.getHeight() / 2); | |
return new Point(revealX, revealY); | |
} | |
protected static int getRevealRadius(@NonNull Point center, @NonNull View view) { | |
float radius = 0; | |
List<Point> points = new ArrayList<>(); | |
points.add(new Point(view.getLeft(), view.getTop())); | |
points.add(new Point(view.getRight(), view.getTop())); | |
points.add(new Point(view.getLeft(), view.getBottom())); | |
points.add(new Point(view.getRight(), view.getBottom())); | |
for (Point point : points) { | |
float distance = distance(center, point); | |
if (distance > radius) { | |
radius = distance; | |
} | |
} | |
return (int) Math.ceil(radius); | |
} | |
public static float distance(Point first, Point second) { | |
return (float) Math.sqrt(Math.pow(first.x - second.x, 2) + Math.pow(first.y - second.y, 2)); | |
} | |
public static Animator fadeIn(@NonNull View view) { | |
return fadeIn(view, ANIMATION_DURATION_DEFAULT); | |
} | |
public static Animator fadeIn(@NonNull View view, int duration) { | |
return fadeIn(view, duration, null); | |
} | |
public static Animator fadeIn(@NonNull View view, @Nullable final AnimationListener listener) { | |
return fadeIn(view, ANIMATION_DURATION_DEFAULT, listener); | |
} | |
public static Animator fadeIn(@NonNull View view, int duration, @Nullable final AnimationListener listener) { | |
if (view.getAlpha() == 1f) { | |
view.setAlpha(0); | |
} | |
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 1f); | |
anim.addListener(new DefaultActionAnimationListener(view, listener) { | |
@Override | |
void defaultOnAnimationStart(@NonNull View view) { | |
view.setVisibility(View.VISIBLE); | |
} | |
}); | |
anim.setDuration(duration); | |
anim.setInterpolator(getDefaultInterpolator()); | |
return anim; | |
} | |
public static Animator fadeOut(@NonNull View view) { | |
return fadeOut(view, ANIMATION_DURATION_DEFAULT); | |
} | |
public static Animator fadeOut(@NonNull View view, int duration) { | |
return fadeOut(view, duration, null); | |
} | |
public static Animator fadeOut(@NonNull View view, @Nullable final AnimationListener listener) { | |
return fadeOut(view, ANIMATION_DURATION_DEFAULT, listener); | |
} | |
public static Animator fadeOut(@NonNull View view, int duration, @Nullable final AnimationListener listener) { | |
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0f); | |
anim.addListener(new DefaultActionAnimationListener(view, listener) { | |
@Override | |
void defaultOnAnimationEnd(@NonNull View view) { | |
view.setVisibility(View.GONE); | |
} | |
}); | |
anim.setDuration(duration); | |
anim.setInterpolator(getDefaultInterpolator()); | |
return anim; | |
} | |
public static Animator verticalSlideView(@NonNull View view, int fromHeight, int toHeight) { | |
return verticalSlideView(view, fromHeight, toHeight, null); | |
} | |
public static Animator verticalSlideView(@NonNull View view, int fromHeight, int toHeight, int duration) { | |
return verticalSlideView(view, fromHeight, toHeight, duration, null); | |
} | |
public static Animator verticalSlideView(@NonNull View view, int fromHeight, int toHeight, @Nullable final AnimationListener listener) { | |
return verticalSlideView(view, fromHeight, toHeight, ANIMATION_DURATION_DEFAULT, listener); | |
} | |
public static Animator verticalSlideView(@NonNull View view, int fromHeight, int toHeight, int duration, @Nullable final AnimationListener listener) { | |
ValueAnimator anim = ValueAnimator | |
.ofInt(fromHeight, toHeight); | |
anim.addUpdateListener(animation -> { | |
view.getLayoutParams().height = (int) (Integer) animation.getAnimatedValue(); | |
view.requestLayout(); | |
}); | |
anim.addListener(new DefaultActionAnimationListener(view, listener)); | |
anim.setDuration(duration); | |
anim.setInterpolator(getDefaultInterpolator()); | |
return anim; | |
} | |
protected static Interpolator getDefaultInterpolator() { | |
return new FastOutSlowInInterpolator(); | |
} | |
public interface AnimationListener { | |
/** | |
* @return return true to override the default behaviour | |
*/ | |
boolean onAnimationStart(@NonNull View view); | |
/** | |
* @return return true to override the default behaviour | |
*/ | |
boolean onAnimationEnd(@NonNull View view); | |
/** | |
* @return return true to override the default behaviour | |
*/ | |
boolean onAnimationCancel(@NonNull View view); | |
} | |
private static class DefaultActionAnimationListener extends AnimatorListenerAdapter { | |
private View view; | |
private AnimationListener listener; | |
DefaultActionAnimationListener(@NonNull View view, @Nullable AnimationListener listener) { | |
this.view = view; | |
this.listener = listener; | |
} | |
@Override | |
public void onAnimationStart(Animator animation) { | |
if (listener == null || !listener.onAnimationStart(view)) { | |
defaultOnAnimationStart(view); | |
} | |
} | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
if (listener == null || !listener.onAnimationEnd(view)) { | |
defaultOnAnimationEnd(view); | |
} | |
} | |
@Override | |
public void onAnimationCancel(Animator animation) { | |
if (listener == null || !listener.onAnimationCancel(view)) { | |
defaultOnAnimationCancel(view); | |
} | |
} | |
void defaultOnAnimationStart(@NonNull View view) { | |
// No default action | |
} | |
void defaultOnAnimationEnd(@NonNull View view) { | |
// No default action | |
} | |
void defaultOnAnimationCancel(@NonNull View view) { | |
// No default action | |
} | |
} | |
} |
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.AnimatorListenerAdapter | |
import android.animation.ObjectAnimator | |
import android.animation.ValueAnimator | |
import android.graphics.Point | |
import android.os.Build | |
import android.view.View | |
import android.view.ViewAnimationUtils | |
import android.view.animation.Interpolator | |
import androidx.annotation.RequiresApi | |
import androidx.interpolator.view.animation.FastOutSlowInInterpolator | |
import java.util.* | |
/** | |
* @author Fernando A. H. Falkiewicz | |
*/ | |
object SimpleAnimationUtils { | |
const val ANIMATION_DURATION_DEFAULT = 250 | |
private val defaultInterpolator: Interpolator | |
get() = FastOutSlowInInterpolator() | |
@JvmOverloads | |
@JvmStatic | |
fun revealOrFadeIn(view: View, duration: Int = ANIMATION_DURATION_DEFAULT, revealCenter: Point? = null, listener: AnimationListener? = null): Animator { | |
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
reveal(view, duration, revealCenter, listener) | |
} else { | |
fadeIn(view, duration, listener) | |
} | |
} | |
@JvmOverloads | |
@JvmStatic | |
fun hideOrFadeOut(view: View, duration: Int = ANIMATION_DURATION_DEFAULT, revealCenter: Point? = null, listener: AnimationListener? = null): Animator { | |
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
hide(view, duration, revealCenter, listener) | |
} else { | |
fadeOut(view, duration, listener) | |
} | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
@JvmOverloads | |
@JvmStatic | |
fun reveal(view: View, duration: Int = ANIMATION_DURATION_DEFAULT, revealCenter: Point? = null, listener: AnimationListener? = null): Animator { | |
val center = revealCenter ?: getDefaultCenter(view) | |
val anim = ViewAnimationUtils.createCircularReveal(view, center.x, center.y, 0f, getRevealRadius(center, view).toFloat()) | |
anim.addListener(object : DefaultActionAnimationListener(view, listener) { | |
override fun defaultOnAnimationStart(view: View) { | |
view.visibility = View.VISIBLE | |
} | |
}) | |
anim.duration = duration.toLong() | |
anim.interpolator = defaultInterpolator | |
return anim | |
} | |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
@JvmOverloads | |
@JvmStatic | |
fun hide(view: View, duration: Int = ANIMATION_DURATION_DEFAULT, revealCenter: Point? = null, listener: AnimationListener? = null): Animator { | |
val center = revealCenter ?: getDefaultCenter(view) | |
val anim = ViewAnimationUtils.createCircularReveal(view, center.x, center.y, getRevealRadius(center, view).toFloat(), 0f) | |
anim.addListener(object : DefaultActionAnimationListener(view, listener) { | |
override fun defaultOnAnimationEnd(view: View) { | |
view.visibility = View.GONE | |
} | |
}) | |
anim.duration = duration.toLong() | |
anim.interpolator = defaultInterpolator | |
return anim | |
} | |
@JvmStatic | |
fun getDefaultCenter(view: View?): Point { | |
if (view == null) | |
return Point() | |
val revealX = (view.x + view.width / 2).toInt() | |
val revealY = (view.y + view.height / 2).toInt() | |
return Point(revealX, revealY) | |
} | |
@JvmStatic | |
fun getRevealRadius(center: Point, view: View): Int { | |
var radius = 0f | |
val points = ArrayList<Point>() | |
points.add(Point(view.left, view.top)) | |
points.add(Point(view.right, view.top)) | |
points.add(Point(view.left, view.bottom)) | |
points.add(Point(view.right, view.bottom)) | |
for (point in points) { | |
val distance = distance(center, point) | |
if (distance > radius) { | |
radius = distance | |
} | |
} | |
return Math.ceil(radius.toDouble()).toInt() | |
} | |
@JvmStatic | |
fun distance(first: Point, second: Point): Float { | |
return Math.sqrt(Math.pow((first.x - second.x).toDouble(), 2.0) + Math.pow((first.y - second.y).toDouble(), 2.0)).toFloat() | |
} | |
@JvmOverloads | |
@JvmStatic | |
fun fadeIn(view: View, duration: Int = ANIMATION_DURATION_DEFAULT, listener: AnimationListener? = null): Animator { | |
if (view.alpha == 1f) { | |
view.alpha = 0f | |
} | |
val anim = ObjectAnimator.ofFloat(view, "alpha", 1f) | |
anim.addListener(object : DefaultActionAnimationListener(view, listener) { | |
override fun defaultOnAnimationStart(view: View) { | |
view.visibility = View.VISIBLE | |
} | |
}) | |
anim.duration = duration.toLong() | |
anim.interpolator = defaultInterpolator | |
return anim | |
} | |
@JvmOverloads | |
@JvmStatic | |
fun fadeOut(view: View, duration: Int = ANIMATION_DURATION_DEFAULT, listener: AnimationListener? = null): Animator { | |
val anim = ObjectAnimator.ofFloat(view, "alpha", 0f) | |
anim.addListener(object : DefaultActionAnimationListener(view, listener) { | |
override fun defaultOnAnimationEnd(view: View) { | |
view.visibility = View.GONE | |
} | |
}) | |
anim.duration = duration.toLong() | |
anim.interpolator = defaultInterpolator | |
return anim | |
} | |
@JvmOverloads | |
@JvmStatic | |
fun verticalSlideView(view: View, fromHeight: Int, toHeight: Int, duration: Int, listener: AnimationListener? = null): Animator { | |
val anim = ValueAnimator | |
.ofInt(fromHeight, toHeight) | |
anim.addUpdateListener { animation -> | |
view.layoutParams.height = animation.animatedValue as Int | |
view.requestLayout() | |
} | |
anim.addListener(DefaultActionAnimationListener(view, listener)) | |
anim.duration = duration.toLong() | |
anim.interpolator = defaultInterpolator | |
return anim | |
} | |
interface AnimationListener { | |
/** | |
* @return return true to override the default behaviour | |
*/ | |
fun onAnimationStart(view: View): Boolean | |
/** | |
* @return return true to override the default behaviour | |
*/ | |
fun onAnimationEnd(view: View): Boolean | |
/** | |
* @return return true to override the default behaviour | |
*/ | |
fun onAnimationCancel(view: View): Boolean | |
} | |
abstract class SimpleAnimationListener : AnimationListener { | |
override fun onAnimationStart(view: View): Boolean { | |
// No action | |
return false | |
} | |
override fun onAnimationEnd(view: View): Boolean { | |
// No action | |
return false | |
} | |
override fun onAnimationCancel(view: View): Boolean { | |
// No action | |
return false | |
} | |
} | |
private open class DefaultActionAnimationListener internal constructor(private val view: View, private val listener: AnimationListener?) : AnimatorListenerAdapter() { | |
override fun onAnimationStart(animation: Animator) { | |
if (listener == null || !listener.onAnimationStart(view)) { | |
defaultOnAnimationStart(view) | |
} | |
} | |
override fun onAnimationEnd(animation: Animator) { | |
if (listener == null || !listener.onAnimationEnd(view)) { | |
defaultOnAnimationEnd(view) | |
} | |
} | |
override fun onAnimationCancel(animation: Animator) { | |
if (listener == null || !listener.onAnimationCancel(view)) { | |
defaultOnAnimationCancel(view) | |
} | |
} | |
internal open fun defaultOnAnimationStart(view: View) { | |
// No default action | |
} | |
internal open fun defaultOnAnimationEnd(view: View) { | |
// No default action | |
} | |
internal fun defaultOnAnimationCancel(view: View) { | |
// No default action | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment