Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotating image. Animation list or animated rotate? (Android)

I want to create a rotating progress image, and wonder what's the best way to proceed. I can make it work with an animation list with for example 12 images changing every 100ms. This works fine, but it's quite tedious to create 12 images or for every size and resolution:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/ic_loading_grey_on_black_01" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_02" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_03" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_04" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_05" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_06" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_07" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_08" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_09" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_10" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_11" android:duration="100" /> <item android:drawable="@drawable/ic_loading_grey_on_black_12" android:duration="100" /> 

I suppose that an easier solution is to use one image per resolution, but rather rotate it for each frame. In the platform resources (android-sdk-windows/platforms...) I found something called animated-rotate in the file drawable/search_spinner.xml, but if I copy the code get a compiler error complaining about android:framesCount and android:frameDuration (Google APIs 2.2 in Eclipse):

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/spinner_black_20" android:pivotX="50%" android:pivotY="50%" android:framesCount="12" android:frameDuration="100" /> 

I have also tried using a repeating rotate animation (using in the anim resource folder), but I actually prefer the look of the animation list version.

What is the recommended way of solving this problem?

like image 674
Gunnar Lium Avatar asked Sep 21 '10 12:09

Gunnar Lium


People also ask

What is rotate animation in Android?

android.view.animation.RotateAnimation. An animation that controls the rotation of an object. This rotation takes place in the X-Y plane. You can specify the point to use for the center of the rotation, where (0,0) is the top left point. If not specified, (0,0) is the default rotation point.

What are the two different types of view animations in Android?

The animations are basically of three types as follows: Property Animation. View Animation. Drawable Animation.

How do I rotate a picture on android?

To change the photo's perspective, tap Transform . Drag the dots to the edges of your desired photo or tap Auto. To rotate a photo 90 degrees, tap Rotate . To make minor adjustments to straighten the photo, use the dial above Rotate .


1 Answers

Rotate drawable suggested by Praveen won't give you control of frame count. Let's assume you want to implement a custom loader which consists from 8 sections:

gif_icon

Using animation-list approach, you need to create 8 frames rotated by 45*frameNumber degrees manually. Alternatively, you can use 1st frame and set rotation animation to it:

progress_icon

File res/anim/progress_anim.xml:

<?xml version="1.0" encoding="utf-8"?> <rotate     xmlns:android="http://schemas.android.com/apk/res/android"     android:fromDegrees="0"     android:toDegrees="360"     android:pivotX="50%"     android:pivotY="50%"     android:repeatCount="infinite" /> 

File MainActivity.java

Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim); a.setDuration(1000); imageView.startAnimation(a); 

This will give you smooth animation instead of 8-stepped. To fix this we need to implement custom interpolator:

a.setInterpolator(new Interpolator() {     private final int frameCount = 8;      @Override     public float getInterpolation(float input) {         return (float)Math.floor(input*frameCount)/frameCount;     } }); 

Also you can create a custom widget:

File res/values/attrs.xml:

<?xml version="1.0" encoding="utf-8"?> <resources>     <declare-styleable name="ProgressView">         <attr name="frameCount" format="integer"/>         <attr name="duration" format="integer" />     </declare-styleable> </resources> 

File ProgressView.java:

public class ProgressView extends ImageView {      public ProgressView(Context context, AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle);         setAnimation(attrs);     }      public ProgressView(Context context, AttributeSet attrs) {         super(context, attrs);         setAnimation(attrs);     }      public ProgressView(Context context) {         super(context);     }      private void setAnimation(AttributeSet attrs) {         TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ProgressView);         int frameCount = a.getInt(R.styleable.ProgressView_frameCount, 12);           int duration = a.getInt(R.styleable.ProgressView_duration, 1000);         a.recycle();          setAnimation(frameCount, duration);     }      public void setAnimation(final int frameCount, final int duration) {         Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim);         a.setDuration(duration);         a.setInterpolator(new Interpolator() {              @Override             public float getInterpolation(float input) {                 return (float)Math.floor(input*frameCount)/frameCount;             }         });         startAnimation(a);     } } 

File activity_main.xml:

<com.example.widget.ProgressView     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:src="@drawable/ic_progress"      app:frameCount="8"     app:duration="1000"/> 

File res/anim/progress_anim.xml: listed above

like image 193
vokilam Avatar answered Sep 19 '22 21:09

vokilam