androidkotlinlintanimator

ValueAnimator Lint Error: This animation should be started with #start() [Recycle]


I'm creating ValueAnimator in init() method like this:

internal var animator: ValueAnimator? = null

@CallSuper
open fun init() {
    animator = ValueAnimator.ofFloat(-1F, 2F)
    animator?.duration = ANIMATION_DURATION
    animator?.interpolator = LinearInterpolator()
    animator?.repeatCount = ValueAnimator.INFINITE
    animator?.repeatMode = ValueAnimator.REVERSE
    animator?.addUpdateListener(this)
}

I'm starting/stopping it depending on the visibility of the view:

override fun onVisibilityChanged(changedView: View, visibility: Int) {
    super.onVisibilityChanged(changedView, visibility)
    when (visibility) {
        VISIBLE -> animator?.start()
        INVISIBLE, GONE -> animator?.cancel()
    }
}

I'm getting the following Lint error:

Error: This animation should be started with #start() [Recycle] animator = ValueAnimator.ofFloat(-1F, 2F) ~~~~~~~

Explanation for issues of type "Recycle": Many resources, such as TypedArrays, VelocityTrackers, etc., should be recycled (with a recycle() call) after use. This lint check looks for missing recycle() calls.

There's no recycle() method for ValueAnimator. I tried to create a new animator each time I need to start it, but I couldn't find a way to provide needed properties without getting this Lint error. How can I fix this?


Solution

  • To avoid the lint error u can create a value animator instance every time when the view is visible like this:-

    fun createAndStartAnim() {
         animator = ValueAnimator.ofFloat(-1F, 2F).apply {
                 duration = ANIMATION_DURATION
                 interpolator = LinearInterpolator()
                 repeatCount = ValueAnimator.INFINITE
                 repeatMode = ValueAnimator.REVERSE
                 addUpdateListener(this@YourUpdateListener)
                 start() // this removes the lint error
         }
    }
    

    We need to cancel by :-

    fun cancelAndNullifyAnim() {
        animator?.cancel()
        animator = null
    }
    

    Now on visibility change:-

    when (visibility) {
            VISIBLE -> createAndStartAnim()
            INVISIBLE, GONE -> cancelAndNullifyAnim()
    }
    

    The lint error should be gone if we start the value anim before accessing any other recyclable properties of it.