Android startActivity rotate 3d animation: ActivitySwitcher

Hi!

Do you know the Transition3d + Rotate3dAnimation from the APIDemos?

I wondered how one could use this animation effect for finishing and starting Activities. Well, this is my solution to it.

*UPDATE 05.12.2011* Working example: ActivitySwitcher

  1. Create a package com.yourapp.animation and copy the Rotate3dAnimation.java in it.
  2. Next, create a new Class yourapp.animation.ActivitySwitcher and implement it like this:

    com.yourapp.animation.ActivitySwitcher.java

    package com.yourapp.animation;
     
    import android.view.Display;
    import android.view.View;
    import android.view.WindowManager;
    import android.view.animation.AccelerateInterpolator;
    import android.view.animation.Animation;
     
    public class ActivitySwitcher {
     
    	private final static int DURATION = 300;
    	private final static float DEPTH = 400.0f;
     
    	/* ----------------------------------------------- */
     
    	public interface AnimationFinishedListener {
    		/**
    		 * Called when the animation is finished.
    		 */
    		public void onAnimationFinished();
    	}
     
    	/* ----------------------------------------------- */
     
    	public static void animationIn(View container, WindowManager windowManager) {
    		animationIn(container, windowManager, null);
    	}
     
    	public static void animationIn(View container, WindowManager windowManager, AnimationFinishedListener listener) {
    		apply3DRotation(90, 0, false, container, windowManager, listener);
    	}
     
    	public static void animationOut(View container, WindowManager windowManager) {
    		animationOut(container, windowManager, null);
    	}
     
    	public static void animationOut(View container, WindowManager windowManager, AnimationFinishedListener listener) {
    		apply3DRotation(0, -90, true, container, windowManager, listener);
    	}
     
    	/* ----------------------------------------------- */
     
    	private static void apply3DRotation(float fromDegree, float toDegree, boolean reverse, View container, WindowManager windowManager, final AnimationFinishedListener listener) {
    		Display display = windowManager.getDefaultDisplay();
    		final float centerX = display.getWidth() / 2.0f;
    		final float centerY = display.getHeight() / 2.0f;
     
    		final Rotate3dAnimation a = new Rotate3dAnimation(fromDegree, toDegree, centerX, centerY, DEPTH, reverse);
    		a.reset();
    		a.setDuration(DURATION);
    		a.setFillAfter(true);
    		a.setInterpolator(new AccelerateInterpolator());
    		if (listener != null) {
    			a.setAnimationListener(new Animation.AnimationListener() {
    				@Override
    				public void onAnimationStart(Animation animation) {
    				}
     
    				@Override
    				public void onAnimationRepeat(Animation animation) {
    				}
     
    				@Override
    				public void onAnimationEnd(Animation animation) {
    					listener.onAnimationFinished();
    				}
    			});
    		}
    		container.clearAnimation();
    		container.startAnimation(a);
    	}
    }
  3. That’s it! Now you can use it like this:

    Activity1.java

    package com.yourapp.activity
     
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import com.yourapp.R;
    import com.yourapp.animation.ActivitySwitcher;
     
    public class Activity1 extends Activity {
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity1);
     
    		Button switchActivityBtn = (Button) findViewById(R.id.bSwitchActivity);
    		switchActivityBtn.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				animatedStartActivity();
    			}
    		});
    	}
     
    	@Override
    	protected void onResume() {
    		// animateIn this activity
    		ActivitySwitcher.animationIn(findViewById(R.id.container), getWindowManager());
    		super.onResume();
    	}
     
    	private void animatedStartActivity() {
    		// we only animateOut this activity here.
    		// The new activity will animateIn from its onResume() - be sure to implement it.
    		final Intent intent = new Intent(getApplicationContext(), Activity2.class);
    		// disable default animation for new intent
    		intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    		ActivitySwitcher.animationOut(findViewById(R.id.container), getWindowManager(), new ActivitySwitcher.AnimationFinishedListener() {
    			@Override
    			public void onAnimationFinished() {
    				startActivity(intent);
    			}
    		});
    	}
    }

    Implement Activity2.java like Activity1.java.

    The layouts (R.layout.activity1 and R.layout.activity1) must jave a container-id like this:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    	android:id="@+id/container"
    	android:orientation="vertical"
    	android:layout_width="fill_parent"
    	android:layout_height="fill_parent">
    	<!-- ... -->
    </LinearLayout>
  4. If you want to animate an activity out when it is finished, you could override the finish() method:
    // ...
    	@Override
    	public void finish() {
    		// we need to override this to performe the animtationOut on each
    		// finish.
    		ActivitySwitcher.animationOut(findViewById(R.id.container), getWindowManager(), new ActivitySwitcher.AnimationFinishedListener() {
    			@Override
    			public void onAnimationFinished() {
    				Activity1.super.finish();
    				// disable default animation
    				overridePendingTransition(0, 0);
    			}
    		});
    	}
    // ...

That’s it! ๐Ÿ™‚

This entry was posted in Career, Software Engineering and tagged , , , , . Bookmark the permalink.

17 Responses to Android startActivity rotate 3d animation: ActivitySwitcher

  1. plabon says:

    there is no method called ActivitySwitcher.animationOut

    Can u provive working code(project)…..it will be helpfull

  2. Robert Heim says:

    Hi and thank you for the hint ๐Ÿ™‚
    I fixed the article and made a working example for you: ActivitySwitcher

    Have fun ๐Ÿ™‚

  3. Edson says:

    thank you, great solution. I’ll try to modify it to have a bar between the views, thought about that?

    Sorry, my english. I’m from Brazil.

  4. Robert Heim says:

    Sorry, I don’t understand what you mean by “bar between the views”. Could you provide a screenshot or explanaition?

  5. Edson says:

    I needed a 3D rotating between activities such as iBooks. I mean that a break occurs in the transition being a dark space when you’re in the middle of the rotation. Thanks.

  6. Rafael Decker says:

    Very usefull. Thanks for the contribution.

  7. Shakti says:

    Hi Thanks a Lot It helped me.

  8. Hรถrรฐur says:

    I see it is an 1.5 year old blog post but still, I stumbled upon it and I have to comment :). The problem with this solution is that your back stack grows bigger and bigger. To avoid this you can add this code in the second activity

    @Override
    public void onBackPressed() {
    ActivitySwitcher.animationOut(findViewById(R.id.container), getWindowManager(), new ActivitySwitcher.AnimationFinishedListener() {
    @Override
    public void onAnimationFinished() {
    Activity2.super.onBackPressed();
    }
    });
    }

    Also, in the middle of the animation there was a slight black blink. If I comment out the line intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); you get the default animation instead for this split second which looks a lot better(at least in android 4.x, check it out).

  9. timeman888 says:

    Thank you for your solution. it give me great help

  10. Igor says:

    Thank you! Nice animation! Thank you for your work!!!

  11. Nafis says:

    I am using a custom Actionbar and want to roatete the (actionbar+page) as container…. Not only the page ….Any Help Please

  12. MacD says:

    Just to add this here (and maybe it’s ’cause I got the wrong version of Rotate3dAnimation.java, but I had a problem with choppiness and overdraw. To fix this, I had to add a few lines in

    protected void applyTransformation(float interpolatedTime, Transformation t)

    after final Matrix matrix = t.getMatrix(); I added:

    t.clear();
    t.setTransformationType(Transformation.TYPE_MATRIX);

    And now the animation runns smooth and without any chop or artifacts!

  13. john m says:

    Right now the actvity switcher is one direction, by that i mean the left goes back and right comes forward.
    when i try to create the opposite: right goes back left comes forward – the view flips inside the activity before actually doing the animation.

  14. john m says:

    I’m trying to flip the screen in the opposite direction. I am able to by setting from degree =-180 and to degree = -90. this works fine aside from the view flipping in place before the animation is started….
    thanks for your help.

  15. pitipong says:

    the id of layout same it’s gonna be ok?

    if i have 10 layout and same id (container) it’s be not have a possible right?

    Thank advance.

  16. sanjay like says:

    thanks man…

Leave a Reply

Your email address will not be published. Required fields are marked *