Skip to content

Instantly share code, notes, and snippets.

@yfujiki
Last active February 28, 2019 14:13
Show Gist options
  • Save yfujiki/7bb72f110e06a93b8f67d0931a93c65f to your computer and use it in GitHub Desktop.
Save yfujiki/7bb72f110e06a93b8f67d0931a93c65f to your computer and use it in GitHub Desktop.
AnimatablePathDrawable
class AnimatablePathDrawable(points: MutableList<NormalizedPoint>,
context: Context)
: PathDrawable(points, context),
ValueAnimator.AnimatorUpdateListener {
// Blue points in the illustration
private val startPoints: MutableList<NormalizedPoint> = mutableListOf()
// Red points in the illustration
private val endPoints: MutableList<NormalizedPoint> = mutableListOf()
private val animator: ValueAnimator = {
// Initialize ValueAnimator instance.
// ValueAnimator is meant to observe the change of value,
// so you have to specify the values (start => end).
// However, we specify rather random values here (0 => 1)
// because we are only interested in progress.
val animator = ValueAnimator.ofInt(0, 1)
// Animation lasts a second.
animator!!.duration = 1000
// Listener's onAnimationUpdate(...) method will be called as animation progresses.
// You can find the implementation is further below in this class.
animator!!.addUpdateListener(this)
animator!!
}()
// The only public method in this class.
// Animation from current points to toEndPoints is going to start
// when you call this method.
fun startAnimating(toEndPoints: List<NormalizedPoint>) {
configureStartEndPoints(points, toEndPoints)
animator.start()
}
private fun configureStartEndPoints(fromStartPoints: List<NormalizedPoint>,
toEndPoints: List<NormalizedPoint>) {
// Calculate corresponding points from end points and update start points.
// Samewise, calculate corresponding points from start points and update end points.
// Actual implementation is explained later.
...
}
// Callback method of ValueAnimator.
override fun onAnimationUpdate(animator: ValueAnimator) {
// Obtain progress.
val fraction = animator.animatedFraction
// Update current points from progress.
points.clear()
startPoints.forEachIndexed({ index, startPoint ->
val endPoint = endPoints[index]
val x = (endPoint.x - startPoint.x) * fraction + startPoint.x
val y = (endPoint.y - startPoint.y) * fraction + startPoint.y
points.add(NormalizedPoint(x, y))
})
// PathDrawable.draw(...) method is triggered by invalidateSelf().
// If you remember, PathDrawable.draw(...) redraws path using the updated points.
invalidateSelf()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment