Last active
September 30, 2021 00:08
-
-
Save vadiole/25a9457066d93ddd8d807fba663eea09 to your computer and use it in GitHub Desktop.
IOS-like shaking animation
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.view.View | |
import java.lang.ref.WeakReference | |
class ShakeController(v: View) { | |
val view: WeakReference<View> = WeakReference(v) | |
private var isShaking = false | |
// rotate and translate bounds, params for random duration | |
private val rotate = 1f | |
private val translate = 0.01f | |
private val minDuration = 120L | |
private val maxDuration = 150L | |
private val rotateAnimator: ValueAnimator = ValueAnimator.ofFloat(-rotate, rotate).apply { | |
val rotateDuration = (minDuration..maxDuration).random() | |
repeatCount = ValueAnimator.INFINITE | |
repeatMode = ValueAnimator.REVERSE | |
duration = rotateDuration | |
currentPlayTime = (rotateDuration / 2) | |
} | |
private val translateAnimator: ValueAnimator = ValueAnimator.ofFloat( | |
(-translate) * v.resources.displayMetrics.density, | |
translate * v.resources.displayMetrics.density | |
).apply { | |
val rotateDuration = (minDuration..maxDuration).random() | |
repeatCount = ValueAnimator.INFINITE | |
repeatMode = ValueAnimator.REVERSE | |
duration = rotateDuration | |
currentPlayTime = (rotateDuration / 2) | |
} | |
private val rotationListener = ValueAnimator.AnimatorUpdateListener { | |
if (view.get()?.isAttachedToWindow == true) { | |
val dX = it.animatedValue as Float | |
view.get()?.rotation = dX | |
} | |
} | |
private val translateListener = ValueAnimator.AnimatorUpdateListener { | |
if (view.get()?.isAttachedToWindow == true) { | |
val dX = it.animatedValue as Float | |
view.get()?.translationX = dX | |
} | |
} | |
init { | |
rotateAnimator.addUpdateListener(rotationListener) | |
translateAnimator.addUpdateListener(translateListener) | |
} | |
fun startShaking() { | |
if (!isShaking) { | |
isShaking = true | |
rotateAnimator.start() | |
translateAnimator.start() | |
view.get()?.rotation = 0f | |
view.get()?.translationX = 0f | |
} | |
} | |
fun stopShaking() { | |
if (isShaking) { | |
isShaking = false | |
rotateAnimator.cancel() | |
translateAnimator.cancel() | |
view.get()?.rotation = 0f | |
view.get()?.translationX = 0f | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment