Search code examples
androidandroid-studioandroid-vectordrawableanimatedvectordrawable

AnimatedVectorDrawable support < 24


I have an animated vector drawable asset in my drawables folder. I use the following code to run it on button click

val myVectorDrawable = ResourcesCompat.getDrawable(
            resources,
            R.drawable.animation,
            theme
        )


        button.setOnClickListener {
            image.setImageDrawable(null)
            image.setImageDrawable(myVectorDrawable)

            val drawable = image.drawable

            if (drawable is AnimatedVectorDrawableCompat) {
                drawable.start()
            } else if (drawable is AnimatedVectorDrawable)
                drawable.start()

        }

This runs perfectly if the device runs an android version > 24 and crashes otherwise. I need to support android devices with minimum SDK 21.

My questions are

  1. How to make my code support devices with 21 up to 24.
  2. is there a better way to run AnimatedVectorDrawable animation

Solution

  • If you know you are using an animated vector, you can use AnimatedVectorDrawableCompat.create() to create an AnimatedVectorDrawableCompat instance that is available on all API 14+ devices:

    val drawable = AnimatedVectorDrawableCompat.create(
        this, // your Context
        R.drawable.animation)
    
    button.setOnClickListener {
        image.setImageDrawable(null)
        image.setImageDrawable(drawable)
    
        drawable.start()
    }
    

    However, if you want a more generic approach, you must instead use AppCompatResources.getDrawable() instead of ResourcesCompat.getDrawable() as that properly takes into account the VectorDrawableCompat, AnimatedVectorDrawableCompat, and AnimatedStateListDrawableCompat classes in a way that is compatible with all API levels:

    val drawable = AppCompatResources.getDrawable(
        this, // your Context
        R.drawable.animation)
    
    button.setOnClickListener {
        image.setImageDrawable(null)
        image.setImageDrawable(drawable)
    
        if (drawable is Animatable) {
            drawable.start()
        }
    }