Tag Archives: viewgroup

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: