65

I've created a layout with an image view and a web view. The web view is set to have a default visibility of gone. When the activity fires up it displays the image view first and when the web view has finished loading its url, it marks itself as visible and the imageview is marked as hidden.

When the imageview is shown, I would like it to rotate repeatedly just for a little added pizazz.

I have never done animations before in Android and all the posts I found when I asked the internet were not helpful; thus, I have returned to SO for help.

So if I start with this...

    final ImageView splash = (ImageView)findViewById(R.id.splash);

How do I create a repeated rotate animation and apply it to the ImageView?

Thanks again!

Praveen
  • 90,477
  • 74
  • 177
  • 219
cakeforcerberus
  • 4,657
  • 6
  • 32
  • 42

9 Answers9

110

Use a RotateAnimation, setting the pivot point to the centre of your image.

RotateAnimation anim = new RotateAnimation(0f, 350f, 15f, 15f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(700);

// Start animating the image
final ImageView splash = (ImageView) findViewById(R.id.splash);
splash.startAnimation(anim);

// Later.. stop the animation
splash.setAnimation(null);
Christopher Orr
  • 110,418
  • 27
  • 198
  • 193
  • 5
    How to set relative pivot points here: new RotateAnimation(0f, 350f, 15f, 15f); Or do I have to check, if the screen is ldpi, mdpi or hdpi before and adjust a multiplier for the pivot values? I also noticed, my picture doesn't return to the original position. Unlike the native android spinner. (I want to use the default android spinner in an image view and make it look just like the original one.) – OneWorld Oct 18 '10 at 15:45
  • 1
    Same question as OneWorld. I don't have a convenient rotation as the coordinates of the pivot center are not correct even if I define as center of the rotation the half of the coordinated obtained by splash.getWidth() and splashgetHeight(). How to solve this issue? – toto_tata Oct 21 '11 at 15:01
53

How to rotate an image around its center:

ImageView view = ... //Initialize ImageView via FindViewById or programatically

RotateAnimation anim = new RotateAnimation(0.0f, 360.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

//Setup anim with desired properties
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE); //Repeat animation indefinitely
anim.setDuration(700); //Put desired duration per anim cycle here, in milliseconds

//Start animation
view.startAnimation(anim); 
//Later on, use view.setAnimation(null) to stop it.

This will cause the image to rotate around its center (0.5 or 50% of its width/height). I am posting this for future readers who get here from Google, as I have, and who wish to rotate the image around its center without defining said center in absolute pixels.

sherpya
  • 4,890
  • 2
  • 34
  • 50
Matt
  • 663
  • 5
  • 8
  • 3
    This was perfect for my requirements. Only change I needed was to specify Animation.RELATIVE_TO_SELF instead of 'Dimension.RelativeToSelf'. – Guru Aug 02 '13 at 01:52
25

You can also simply use the Rotate animation feature. That runs a specific animation, for a pre-determined amount of time, on an ImageView.

Animation rotate = AnimationUtils.loadAnimation([context], R.anim.rotate_picture);
splash.startAnimation(rotate);

Then create an animation XML file in your res/anim called rotate_picture with the content:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shareInterpolator="false">

    <rotate 
    android:fromDegrees="0"
    android:toDegrees="360"
    android:duration="5000"
    android:pivotX="50%"
    android:pivotY="50%">
</rotate>
</set>

Now unfortunately, this will only run it once. You'll need a loop somewhere to make it repeat the animation while it's waiting. I experimented a little bit and got my program stuck in infinite loops, so I'm not sure of the best way to that. EDIT: Christopher's answer provides the info on how to make it loop properly, so removing my bad suggestion about separate threads!

Steve Haley
  • 55,374
  • 17
  • 77
  • 85
11

One way - split you image into N rotating it slightly every time. I'd say 5 is enough. then create something like this in drawable

<animation-list   android:id="@+id/handimation" android:oneshot="false" 
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/progress1" android:duration="150" />
    <item android:drawable="@drawable/progress2" android:duration="150" />
    <item android:drawable="@drawable/progress3" android:duration="150" />
 </animation-list> 

code start

progress.setVisibility(View.VISIBLE);
AnimationDrawable frameAnimation = (AnimationDrawable)progress.getDrawable();
frameAnimation.setCallback(progress);
frameAnimation.setVisible(true, true);

code stop

AnimationDrawable frameAnimation = (AnimationDrawable)progress.getDrawable();
frameAnimation.stop();
frameAnimation.setCallback(null);
frameAnimation = null;
progress.setVisibility(View.GONE);

more here

makvalti
  • 87
  • 1
  • 9
Alex Volovoy
  • 67,778
  • 13
  • 73
  • 54
  • Thanks for documenting this solution. Even though the rotation answer given by others suits the purpose of the original question, your solution is just what I'm looking for to animate in other ways. – CodeChimp Sep 12 '12 at 09:03
  • 1
    This would be an awful way of achieving the desired aim when there is already a rotate animation. Why do it all manually : huge resource storage overheads. – RichieHH Jul 20 '14 at 12:57
7
imgDics = (ImageView) v.findViewById(R.id.img_player_tab2_dics);
    imgDics.setOnClickListener(onPlayer2Click);
    anim = new RotateAnimation(0f, 360f,
            Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                            0.5f);
    anim.setInterpolator(new LinearInterpolator());
    anim.setRepeatCount(Animation.INFINITE);
    anim.setDuration(4000);

    // Start animating the image
    imgDics.startAnimation(anim);
son nt
  • 147
  • 2
  • 5
6

Inside the element put:

android:repeatCount="infinite"
Andrew Mackenzie
  • 5,477
  • 5
  • 48
  • 70
3

I have found out, that if you use the .getWidth/2 etc... that it won't work you need to get the number of pixels the image is and divide it by 2 yourself and then just type in the number for the last 2 arguments.

so say your image was a 120 pixel by 120 pixel square, ur x and y would equal 60 pixels. so in your code, you would right:

RotateAnimation anim = new RotateAnimation(0f, 350f, 60f, 60f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(700);

and now your image will pivot round its center.

Fahim Parkar
  • 30,974
  • 45
  • 160
  • 276
2

Verified Code:

imageView.setImageResource(R.drawable.ic_arrow_up);

boolean up = true;

if (!up) { 
    up = true; 
    imageView.startAnimation(animate(up)); 
} else { 
    up = false; 
    imageView.startAnimation(animate(up)); 
}

private Animation animate(boolean up) {
    Animation anim = AnimationUtils.loadAnimation(this, up ? R.anim.rotate_up : R.anim.rotate_down);
    anim.setInterpolator(new LinearInterpolator()); // for smooth animation
    return anim;
}

drawable/ic_arrow_up.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#3d3d3d"
        android:pathData="M7.41,15.41L12,10.83l4.59,4.58L18,14l-6,-6 -6,6z"/>
</vector>

anim/rotate_up.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:fillEnabled="true">
    <rotate
        android:duration="200"
        android:fromDegrees="-180"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="0" />
</set>

anim/rotate_down.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:fillEnabled="true">
    <rotate
        android:duration="200"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="180" />
</set>
Ahamadullah Saikat
  • 4,437
  • 42
  • 39
0

Don't hard code image bounds. Just use:

RotateAnimation anim = new RotateAnimation( fromAngle, toAngle, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
nick shp
  • 90
  • 1
  • 9