Home » Android » Android: How to maintain aspect-ratio in animation

Android: How to maintain aspect-ratio in animation

Posted by: admin June 15, 2020 Leave a comment

Questions:

The animation I am running inside an imageview refuses to maintain the aspect-ratio of the image frames. The following answers in SO are quite informative, but don’t seem to work for me:
How to scale an Image in ImageView to keep the aspect ratio

Here is the code:

private void startAnimation(){
    mImageView.setAdjustViewBounds(true);
    mImageView.setScaleType(ScaleType.CENTER);
    mImageView.setBackgroundResource(R.anim.my_animation);

    AnimationDrawable frameAnimation = (AnimationDrawable) mImageView.getBackground();

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

R.anim.my_animation is just an animation list:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/selected"
android:oneshot="false">
<item
    android:drawable="@drawable/photo_1"
    android:duration="100" />
<item
    android:drawable="@drawable/photo__2"
    android:duration="100" />
    ... and so on...
</animation-list>
How to&Answers:

Instead of setting the animation drawable in the background of the imageview, set it in the foreground using src and let the animation play there. All images in the frame animation will be resized with aspect ratio intact provided you set a suitable scale type for the imageview.

    private void startAnimation(){
    mImageView.setAdjustViewBounds(true);
    mImageView.setScaleType(ScaleType.CENTER);
    mImageView.setImageDrawable(getResources().getDrawable(R.anim.my_animation)); 

    AnimationDrawable frameAnimation = (AnimationDrawable) mImageView.getDrawable();

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

Answer:

This is a bit tricky but it works.
I have two pictures in my animation-list

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/selected" android:oneshot="false">
    <item android:drawable="@drawable/logo1" android:duration="5000" />
    <item android:drawable="@drawable/logo2" android:duration="300" />
</animation-list>

Then I added a third picture (logo0) that is the same size of logo1/2 but it is fully transparent.
Finally I use this ImageView:

<ImageView
    android:id="@+id/imageViewLogo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:adjustViewBounds="true"
    android:layout_margin="5dp"
    android:src="@drawable/logo0"
/>

Now my animation preserves the aspect ratio of my pictures logo*.

The code is:

    @Override
    public void onCreate(Bundle savedInstanceState) {
    ...
    imageView = (ImageView) findViewById(R.id.imageViewLogo);
    imageView.setBackgroundResource(R.drawable.logo_animation);
    ...


    public void onWindowFocusChanged (boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
     AnimationDrawable frameAnimation = (AnimationDrawable) imageView.getBackground();
     if(hasFocus) { frameAnimation.start(); } else { frameAnimation.stop(); }
    }

It is very simple and it costs just an extra dummy pictures to you resources: no extra code, no complex calculations.