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
- Create a package com.yourapp.animation and copy the Rotate3dAnimation.java in it.
- 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); } }
- 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
andR.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>
- 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! ๐
there is no method called ActivitySwitcher.animationOut
Can u provive working code(project)…..it will be helpfull
Hi and thank you for the hint ๐
I fixed the article and made a working example for you: ActivitySwitcher
Have fun ๐
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.
Sorry, I don’t understand what you mean by “bar between the views”. Could you provide a screenshot or explanaition?
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.
Very usefull. Thanks for the contribution.
Hi Thanks a Lot It helped me.
Nice Tutorial
I need suggestion like http://stackoverflow.com/questions/12274943/3d-animation-between-activity-in-android
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).
Thank you for your solution. it give me great help
Thank you! Nice animation! Thank you for your work!!!
I am using a custom Actionbar and want to roatete the (actionbar+page) as container…. Not only the page ….Any Help Please
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!
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.
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.
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.
thanks man…