Creating a 3D flip animation in Android using XML
Here is the answer, though it only works with 3.0 and above.
1) Create a new resources folder called "animator".
2) Create a new .xml file which I will call "flipping". Use the following xml code:
<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:valueFrom="0" android:valueTo="360" android:propertyName="rotationY" ></objectAnimator>
No, the objectAnimator tags do not start with an uppercase "O".
3) Start the animation with the following code:
ObjectAnimator anim = (ObjectAnimator) AnimatorInflater.loadAnimator(mContext, R.animator.flipping); anim.setTarget(A View Object reference goes here i.e. ImageView);anim.setDuration(3000);anim.start();
I got all this from here.
Since the answers to this question are fairly dated, here is a more modern solution relying on ValueAnimators.This solution implements a true, visually appealing 3D-flip, because it not just flips the view, but also scales it while it is flipping (this is how Apple does it).
First we set up the ValueAnimator:
mFlipAnimator = ValueAnimator.ofFloat(0f, 1f);mFlipAnimator.addUpdateListener(new FlipListener(frontView, backView));
And the corresponding update listener:
public class FlipListener implements ValueAnimator.AnimatorUpdateListener { private final View mFrontView; private final View mBackView; private boolean mFlipped; public FlipListener(final View front, final View back) { this.mFrontView = front; this.mBackView = back; this.mBackView.setVisibility(View.GONE); } @Override public void onAnimationUpdate(final ValueAnimator animation) { final float value = animation.getAnimatedFraction(); final float scaleValue = 0.625f + (1.5f * (value - 0.5f) * (value - 0.5f)); if(value <= 0.5f){ this.mFrontView.setRotationY(180 * value); this.mFrontView.setScaleX(scaleValue); this.mFrontView.setScaleY(scaleValue); if(mFlipped){ setStateFlipped(false); } } else { this.mBackView.setRotationY(-180 * (1f- value)); this.mBackView.setScaleX(scaleValue); this.mBackView.setScaleY(scaleValue); if(!mFlipped){ setStateFlipped(true); } } } private void setStateFlipped(boolean flipped) { mFlipped = flipped; this.mFrontView.setVisibility(flipped ? View.GONE : View.VISIBLE); this.mBackView.setVisibility(flipped ? View.VISIBLE : View.GONE); }}
That's it!
After this setup you can flip the views by calling
mFlipAnimator.start();
and reverse the flip by calling
mFlipAnimator.reverse();
If you want to check if the view is flipped, implement and call this function:
private boolean isFlipped() { return mFlipAnimator.getAnimatedFraction() == 1;}
You can also check if the view is currently flipping by implementing this method:
private boolean isFlipping() { final float currentValue = mFlipAnimator.getAnimatedFraction(); return (currentValue < 1 && currentValue > 0);}
You can combine the above functions to implement a nice function to toggle the flip, depending on if it is flipped or not:
private void toggleFlip() { if(isFlipped()){ mFlipAnimator.reverse(); } else { mFlipAnimator.start(); }}
That's it! Simple and easy. Enjoy!
I have created a simple program for creating flip of view like :
In Activity you have to create this method, for adding flip_rotation in view.
private void applyRotation(View view) { final Flip3dAnimation rotation = new Flip3dAnimation(view); rotation.applyPropertiesInRotation(); view.startAnimation(rotation);}
for this, you have to copy main class used to provide flip_rotation.
import android.graphics.Camera;import android.graphics.Matrix;import android.util.Log;import android.view.View;import android.view.animation.AccelerateInterpolator;import android.view.animation.Animation;import android.view.animation.Transformation;public class Flip3dAnimation extends Animation { private final float mFromDegrees; private final float mToDegrees; private final float mCenterX; private final float mCenterY; private Camera mCamera; public Flip3dAnimation(View view) { mFromDegrees = 0; mToDegrees = 720; mCenterX = view.getWidth() / 2.0f; mCenterY = view.getHeight() / 2.0f; } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); mCamera = new Camera(); } public void applyPropertiesInRotation() { this.setDuration(2000); this.setFillAfter(true); this.setInterpolator(new AccelerateInterpolator()); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { final float fromDegrees = mFromDegrees; float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera; final Matrix matrix = t.getMatrix(); camera.save(); Log.e("Degree",""+degrees) ; Log.e("centerX",""+centerX) ; Log.e("centerY",""+centerY) ; camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); }}