3D Flip Between Two View or ViewGroup on Android

3D flip makes a nice effect. It seems like there is no good android implementation on the internet that shows how to make two generic view flip with each other. Let me first show you the end result, the card flips if you clicking on it anywhere.

First the activity layout file:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_activity_root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/transparent" >

<RelativeLayout
android:id="@+id/main_activity_card_face"
android:layout_width="300dp"
android:layout_height="407dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="@drawable/front"
android:clickable="true"
android:onClick="onCardClick"
android:padding="5dp" >
</RelativeLayout>

<RelativeLayout
android:id="@+id/main_activity_card_back"
android:layout_width="300dp"
android:layout_height="407dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="@drawable/back"
android:clickable="true"
android:onClick="onCardClick"
android:visibility="gone" >
</RelativeLayout>

</RelativeLayout>

As the layout file flips two view groups you could put anything else inside the view group and it should work. Now lets look at the methods inside the activity which handles calling the flip animation code:

public void onCardClick(View view)
{
      flipCard();
}

private void flipCard()
{
	View rootLayout = (View) findViewById(R.id.main_activity_root);
	View cardFace = (View) findViewById(R.id.main_activity_card_face);
	View cardBack = (View) findViewById(R.id.main_activity_card_back);

	FlipAnimation flipAnimation = new FlipAnimation(cardFace, cardBack);

	if (cardFace.getVisibility() == View.GONE)
	{
		flipAnimation.reverse();
	}
	rootLayout.startAnimation(flipAnimation);
}

And finally the FlipAnimation class:

public class FlipAnimation extends Animation
{
    private Camera camera;

    private View fromView;
    private View toView;

    private float centerX;
    private float centerY;

    private boolean forward = true;

    /**
     * Creates a 3D flip animation between two views.
     *
     * @param fromView First view in the transition.
     * @param toView Second view in the transition.
     */
	public FlipAnimation(View fromView, View toView)
    {
        this.fromView = fromView;
        this.toView = toView;

		setDuration(700);
        setFillAfter(false);
        setInterpolator(new AccelerateDecelerateInterpolator());
    }

    public void reverse()
    {
        forward = false;
		View switchView = toView;
        toView = fromView;
        fromView = switchView;
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight)
    {
        super.initialize(width, height, parentWidth, parentHeight);
        centerX = width/2;
        centerY = height/2;
        camera = new Camera();
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t)
    {
        // Angle around the y-axis of the rotation at the given time
        // calculated both in radians and degrees.
        final double radians = Math.PI * interpolatedTime;
        float degrees = (float) (180.0 * radians / Math.PI);

        // Once we reach the midpoint in the animation, we need to hide the
        // source view and show the destination view. We also need to change
        // the angle by 180 degrees so that the destination does not come in
        // flipped around
        if (interpolatedTime >= 0.5f)
        {
            degrees -= 180.f;
            fromView.setVisibility(View.GONE);
            toView.setVisibility(View.VISIBLE);
        }

        if (forward)
            degrees = -degrees; //determines direction of rotation when flip begins

        final Matrix matrix = t.getMatrix();
        camera.save();
        camera.rotateY(degrees);
        camera.getMatrix(matrix);
        camera.restore();
        matrix.preTranslate(-centerX, -centerY);
        matrix.postTranslate(centerX, centerY);
    }

The FlipAnimation code was borrowed from code I found somewhere on internet. I can’t find reference to it anymore so if anyone happens to find anything similar please provide reference in the comments and I’ll link it up. The images I used in the code you can grab similar images from here.

Try modifying the code and making a flip around X axis and if you read this far consider following me on Twitter:

Advertisements

18 thoughts on “3D Flip Between Two View or ViewGroup on Android

  1. Kc

    I am trying to make card flip Animation when an item(card) is clicked in the google card list view animation https://github.com/nhaarman/ListViewAnimations
    my values..
    View rootLayout = listView.getChildAt(0);
    View cardFace = listView.getChildAt(0);
    View cardBack = listView.getChildAt(1);

    In my case, the card been flipped is the first item in a listview and i want the cards back to be the second items view(card) on my listview. But when i put the values above in, the card flips(with the card face as the back instead of the specified card-back) and then disappears leaving a blank view behind.
    here is my acttivity: http://pastebin.com/ff1x72yt
    my xml: http://pastebin.com/MZ5ePjkE
    pls help me with ideas on how to get the specified view and use it in the flip animation.
    any suggestions would be appreciated

    Reply
  2. ettibo

    Thank you very much, it’s very helpfull.
    I just have a question, when the rotation is occuring, there is a white screen behind.
    Anyway to put it in black?

    Thanks ๐Ÿ™‚

    Reply
    1. 2cupsoftech Post author

      All the source code you need is in the post. You just need to put the files together in one single project.

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s