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);
}
}
Very informational post!
ReplyDeleteThank you :)
DeleteThank you Yashwanth, great post.
ReplyDeleteYashwanth Garu very very thanks........................
ReplyDeletebut one probel ur code
ReplyDeleteHello, but when ever I'm touching the image, it getting rotated some angle automatically, can you help me with that?,.Thank you
ReplyDeleteHaving the same issue... you can try removing 90...not the best but for this moment it is what I am using...
DeleteMath.toDegrees(Math.atan2(x - xc, yc - y))-90;
This comment has been removed by the author.
DeleteHello, i solved by commenting wheel.clearAnimation();
DeleteAlso 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
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?
ReplyDeleteVery, Very, Very helpful THANKS!!
ReplyDeleteHi, 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.
ReplyDeletefinal RotateAnimation rotate = new RotateAnimation((float) fromDegrees, (float) toDegrees,RotateAnimation.RELATIVE_TO_SELF, 0.5f,RotateAnimation.RELATIVE_TO_SELF, 0.5f);
Deleterotate.setDuration(durationMillis);
rotate.setFillEnabled(true);
rotate.setFillAfter(true);
if(mCurrAngle<=90 && mCurrAngle>-90) // 180 degree
{
wheel.startAnimation(rotate);
System.out.println(mCurrAngle);
}
Thanks bro. Works like a charm! Thumbs up.
DeleteIt works,but how to rotate it to -270 and +270 degree like a real steering wheel,thinks
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteWow 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.
ReplyDeleteAny kind of help will be appreciated. Thanks in Advance.
And the same thing, how can we make the image appear as Sphere (I mean 3D).
ReplyDeleteActually 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.
thanks
ReplyDeletehttps://stackoverflow.com/questions/6578320/how-to-apply-zoom-drag-and-rotation-to-an-image-in-android/47861501#47861501
ReplyDeleteThanks 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 |
ReplyDeletehow do I implement the logic for accelerator?
ReplyDelete