Saturday 17 May 2014

How to animate an image to rotate with your finger touch in android

A simple animation to rotate an image with finger touch both left and right.


Lets see how to rotate image with 2D animation. I've used a steering wheel for this to make some sense.





Step 1 : Place an image file in your xml layout.

activity_main.xml :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff" >

<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:src="@drawable/wheel"
android:contentDescription="@string/wheel" />

</RelativeLayout>


Step 2 : Let the main class implement onTouchListener and use the MotionEvent for rotation. Just copy the below code.

MainActivity.java :

package com.exampl.simplegame;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;

public class MainActivity extends Activity implements OnTouchListener{
private ImageView wheel;
private double mCurrAngle = 0;
private double mPrevAngle = 0;
ImageView bask;

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

wheel=(ImageView)findViewById(R.id.imageView1);
wheel.setOnTouchListener(this);
}

@Override
public boolean onTouch(final View v, MotionEvent event) {
final float xc = wheel.getWidth() / 2;
final float yc = wheel.getHeight() / 2;

final float x = event.getX();
final float y = event.getY();

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
wheel.clearAnimation();
mCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
break;
}
case MotionEvent.ACTION_MOVE: {
mPrevAngle = mCurrAngle;
mCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
animate(mPrevAngle, mCurrAngle, 0);
System.out.println(mCurrAngle);
break;
}
case MotionEvent.ACTION_UP : {
mPrevAngle = mCurrAngle = 0;
break;
}
}
return true;
}

private void animate(double fromDegrees, double toDegrees, long durationMillis) {
final RotateAnimation rotate = new RotateAnimation((float) fromDegrees, (float) toDegrees,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(durationMillis);
rotate.setFillEnabled(true);
rotate.setFillAfter(true);
wheel.startAnimation(rotate);
System.out.println(mCurrAngle);
}
}

22 comments:

  1. Very informational post!

    ReplyDelete
  2. Thank you Yashwanth, great post.

    ReplyDelete
  3. Yashwanth Garu very very thanks........................

    ReplyDelete
  4. Hello, but when ever I'm touching the image, it getting rotated some angle automatically, can you help me with that?,.Thank you

    ReplyDelete
    Replies
    1. Having the same issue... you can try removing 90...not the best but for this moment it is what I am using...

      Math.toDegrees(Math.atan2(x - xc, yc - y))-90;

      Delete
    2. This comment has been removed by the author.

      Delete
    3. Hello, i solved by commenting wheel.clearAnimation();
      Also i have commented:

      // mCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));

      And on ActionDown i have:

      mPrevAngle = mCurrAngle; // instead of mPrevAngle = mCurrAngle = 0;

      I don't know if these last two lines makes a difference, you can have a try by commenting/uncommenting them

      Delete
  5. Great! I have a question, how can I let the image snap to a point. I have 12 point that I want the circle to snap to, meaning that when the user release the screen it snaps to the closest point?

    ReplyDelete
  6. Very, Very, Very helpful THANKS!!

    ReplyDelete
  7. Hi, I like your tutorial. However I have a question, how do you limit the rotation for example from left starting 0 to right up to 90 degrees only? I want to avoid the negative value of rotation for some reason. Thanks in advance.

    ReplyDelete
    Replies
    1. final RotateAnimation rotate = new RotateAnimation((float) fromDegrees, (float) toDegrees,RotateAnimation.RELATIVE_TO_SELF, 0.5f,RotateAnimation.RELATIVE_TO_SELF, 0.5f);
      rotate.setDuration(durationMillis);
      rotate.setFillEnabled(true);
      rotate.setFillAfter(true);
      if(mCurrAngle<=90 && mCurrAngle>-90) // 180 degree
      {
      wheel.startAnimation(rotate);
      System.out.println(mCurrAngle);
      }

      Delete
    2. Thanks bro. Works like a charm! Thumbs up.

      Delete
  8. It works,but how to rotate it to -270 and +270 degree like a real steering wheel,thinks

    ReplyDelete
  9. This comment has been removed by the author.

    ReplyDelete
  10. Wow its great, but I wonder if you could do flip image in android, like 3d rectangular image where there is front and back side and we can use it both way i.e front and back.
    Any kind of help will be appreciated. Thanks in Advance.

    ReplyDelete
  11. And the same thing, how can we make the image appear as Sphere (I mean 3D).
    Actually I want to rotate a sphere to 360 degrees anywhere the user wants, like a globe.
    How can I make that working ?

    Please help me with this. I am new to Android.

    ReplyDelete
  12. https://stackoverflow.com/questions/6578320/how-to-apply-zoom-drag-and-rotation-to-an-image-in-android/47861501#47861501

    ReplyDelete
  13. Thanks for such a great article here. I was searching for something like this for quite a long time and at last I’ve found it on your blog. It was definitely interesting for me to read about their market situation nowadays. project management courses in chennai | pmp training class in chennai | pmp training fee | project management training certification | project management training in chennai | project management certification online |

    ReplyDelete
  14. how do I implement the logic for accelerator?

    ReplyDelete