Skip to content

Instantly share code, notes, and snippets.

@sergiocasero
Last active June 30, 2017 10:56
Show Gist options
  • Save sergiocasero/fa7e87ee7041211fa62ad924c1275d8f to your computer and use it in GitHub Desktop.
Save sergiocasero/fa7e87ee7041211fa62ad924c1275d8f to your computer and use it in GitHub Desktop.
Reveal animations for views (Android)
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.annotation.TargetApi
import android.os.Build
import android.view.View
import android.view.ViewAnimationUtils
/**
* Animation.
*/
/**
* Simple reveal, expands from screen center
* */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun View.enterReveal() {
val cx = measuredWidth / 2
val cy = measuredHeight / 2
val finalRadius = Math.max(width, height) / 2
val anim = ViewAnimationUtils.createCircularReveal(this, cx, cy, 0f, finalRadius.toFloat())
visibility = View.VISIBLE
anim.start()
}
/**
* Expands from divider, for example, from width and height / 4 to screen
* Divider must be > 0
* */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun View.enterReveal(divider: Int, callback: () -> Any) {
if (divider <= 0) {
throw IllegalArgumentException("Didiver must be > 0")
}
val cx = measuredWidth / divider
val cy = measuredHeight / divider
val finalRadius = Math.max(width, height) / divider
val anim = ViewAnimationUtils.createCircularReveal(this, cx, cy, 0f, finalRadius.toFloat())
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
callback.invoke()
}
})
visibility = View.VISIBLE
anim.start()
}
/**
* Expands from the center of "startRevealView"
* Divider must be > 0
* */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun View.enterReveal(startRevealView: View, divider: Int, callback: () -> Any) {
if (divider <= 0) {
throw IllegalArgumentException("Didiver must be > 0")
}
val location = IntArray(2)
startRevealView.getLocationInWindow(location)
val cx = location[0] + startRevealView.measuredWidth / 2
val cy = location[1] + startRevealView.measuredHeight / 2
val finalRadius = Math.max(width, height) / divider
val anim = ViewAnimationUtils.createCircularReveal(this, cx, cy, 0f, finalRadius.toFloat())
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
callback.invoke()
}
})
visibility = View.VISIBLE
anim.start()
}
/***
* From the window (divider = 1) or the divider to the center of the reveal view
* Divider must be > 0
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun View.exitReveal(endRevealView: View, divider: Int) {
if (divider <= 0) {
throw IllegalArgumentException("Didiver must be > 0")
}
val location = IntArray(2)
endRevealView.getLocationInWindow(location)
val cx = location[0] + endRevealView.measuredWidth / 2
val cy = location[1] + endRevealView.measuredHeight / 2
val initialRadius = Math.max(width, height) / divider
val anim = ViewAnimationUtils.createCircularReveal(this, cx, cy, initialRadius.toFloat(), 0f)
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
visibility = View.INVISIBLE
}
})
anim.start()
}
/**
* From the window to the center
* */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun View.exitReveal() {
// previously visible view
// get the center for the clipping circle
val cx = measuredWidth / 2
val cy = measuredHeight / 2
// get the initial radius for the clipping circle
val initialRadius = width / 2
// create the animation (the final radius is zero)
val anim = ViewAnimationUtils.createCircularReveal(this, cx, cy, initialRadius.toFloat(), 0f)
// make the view invisible when the animation is done
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
visibility = View.INVISIBLE
}
})
// start the animation
anim.start()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment