Viewをグルグル回転させて初期角度で止めるには (How to reset angle rotation to default?)
2021/06/21

Viewを回転させるにはいくつか方法がありますが、今回はリピート設定のないViewPropertyAnimatorを使います。回転を始めて、ストップした時にすぐに止めないで、終了リスナーを上書きしてリピートされないようにしておきます。
通信中にNow Loadingで回転させるボタンを作ってみました。
class ProgressButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : MaterialButton(context, attrs, defStyle) {
fun startRotating(duration: Long = 1200, angle: Float = 360f) {
var runnable: Runnable? = null
runnable = Runnable {
animate()
.rotationBy(angle)
.setDuration(duration)
.setInterpolator(LinearInterpolator())
// .withEndAction can not be changed during the animation
.setListener(object: Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator?) {}
override fun onAnimationCancel(animation: Animator?) {}
override fun onAnimationRepeat(animation: Animator?) {}
override fun onAnimationEnd(animation: Animator?) { runnable?.run() }
})
.start()
}
isClickable = false
runnable.run()
}
fun stopRotating() {
animate()
.setListener(object: Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator?) {}
override fun onAnimationCancel(animation: Animator?) {}
override fun onAnimationRepeat(animation: Animator?) {}
override fun onAnimationEnd(animation: Animator?) { isClickable = true }
})
}
}
ちなみに、リスナーのonAnimationCancelは不測の事態でキャンセルされた時に呼ばれるものではなく、animate().cancel()で停止させた時に呼ばれるもので、onAnimationCancel -> onAnimationEnd、の順で呼ばれます。