Android: How to maintain aspect-ratio in animation
Asked Answered
A

2

10

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>
Amphithecium answered 16/5, 2011 at 16:33 Comment(2)
According to the question you referenced, the solution lied in the XML layout. Post your XML layout so we can verify you are defining the parameters correctly.Entoderm
@user432209: +1. You helped me figure out my mistake. I had set the imageview height & width to absolute values (since it shows some stuff other than the animation). Removing that resolved the issue. Thanks!Amphithecium
F
13

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();
}
Famish answered 24/12, 2013 at 18:43 Comment(2)
I upvoted your answer for solving my problem. Note you can only use mImageView.setImageResource(R.anim.my_animation) for short.Deledda
Thanks, this trick works for vector images too!!Understructure
H
0

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.

Horner answered 11/3, 2013 at 22:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.