Search code examples
javaandroidxmlanimated-gif

One XML file with many animation-lists instead of many XML files with one animation-list (Android - Java)


I made a GIF from 2 JPGs photos, using the spin_animation.xml, according to the relative Android Developers tutorial.
It works fine.
But I want to change the GIF inside the ImageView in my layout. Basically, I want to change it to 50 different GIFs.

Is there a better and less silliest way to do that, instead of creating 50 spin_animation.xml, one for each GIF ? For example, is there a way to use the id that I gave to the animation-list inside it ?


In my .java file, in the onCreate method, I call the spin_animation.xml in order to make a gif the 2 jpg pictures that I have in my drawables. My .java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_progress);

    // Load the ImageView that will host the animation and
     // set its background to our AnimationDrawable XML resource.
     ImageView img = (ImageView)findViewById(R.id.imageView1);
     img.setBackgroundResource(R.drawable.spin_animation);

     // Get the background, which has been compiled to an AnimationDrawable object.
     AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();

     // Start the animation (looped playback by default).
     frameAnimation.start();

}

My spin_animation.xml file in my drawable contains:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/selected" android:oneshot="false">
    <item android:drawable="@drawable/barbellcurl1" android:duration="1000" />
    <item android:drawable="@drawable/barbellcurl2" android:duration="1000" />   
</animation-list>

And at last my ImageView in my .xml layout:

 <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="106dp" />


Solution

  • You can create or modify animation drawables at runtime if you like:

    AnimationDrawable createFrom(Context context, int id1, int id2) {
        AnimationDrawable ad = new AnimationDrawable();
        ad.addFrame(context.getResources().getDrawable(id1), 1000);
        ad.addFrame(context.getResources().getDrawable(id2), 1000);
        return ad;
    }
    

    Using above, you could do:

    ImageView img = (ImageView)findViewById(R.id.imageView1);
    img.setBackground(createFrom(this, R.drawable.barbellcurl1, R.drawable.barbellcurl2));
    

    and you should still have the same result.


    You can also define those drawables in a xml array: http://developer.android.com/guide/topics/resources/more-resources.html#TypedArray - the advantage is that you have to write less code and you can now define all your "gif"s in a single xml file.

    Using a typed array should work like this:

    AnimationDrawable createFromArray(Context context, int arrayId) {
        TypedArray array = context.getResources().obtainTypedArray(arrayId);
        AnimationDrawable ad = new AnimationDrawable();
        for (int i = 0; i < array.length(); i++) {
            ad.addFrame(array.getDrawable(i), 1000);
        }
        array.recycle();
        return ad;
    }
    

    The content of the XML file would look like res/values/gifs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <array name="gif1">
            <item>@drawable/barbellcurl1</item>
            <item>@drawable/barbellcurl2</item>
        </array>
        <array name="gif2">
            <item>@drawable/cat</item>
            <item>@drawable/dog</item>
        </array>
    </resources>
    

    And to get a drawable in code you would do createFromArray(this, R.array.gif1) etc.


    The code in onCreate in the end would be

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_progress);
    
         ImageView img = (ImageView)findViewById(R.id.imageView1);
    
         AnimationDrawable ad = createFrom(this, R.drawable.barbellcurl1, R.drawable.barbellcurl2);
         // OR
         AnimationDrawable ad = createFromArray(this, R.array.gif1);
    
         ad.setOneShot(false);
         img.setBackground(ad);
         ad.start();
    }