6

Changing activities with an animation is possible using the code below:

Bundle animation = ActivityOptions.makeCustomAnimation(App.getContext(), R.anim.enter_from_right, R.anim.exit_to_left).toBundle();
startActivity(intent, animation);

For fragments you can do something similar on FragmentTransaction:

// ...
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left);
// ...

This works! But I'd like to have an animation when pressing back (pop from backstack). For fragments you simply add 2 anim resources (popEnter & popExit):

transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);

How can I create the same 'back-animation' for activities?

Lorenzo Polidori
  • 10,332
  • 10
  • 51
  • 60
P Kuijpers
  • 1,593
  • 15
  • 27
  • 1
    I used this code: `overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);` You can see these examples in [GmailAnimation](https://github.com/CabezasGonzalezJavier/GmailAnimation) or [LopeAnimations](https://github.com/CabezasGonzalezJavier/LopeAnimations). Also you can see more in this [Blog](http://thedeveloperworldisyours.com/android/gmail-overriding-pending-transition/#sthash.CEhJwJLg.dpbs). – Cabezas Feb 15 '17 at 12:10
  • I've answerred my ow question with that same example, but extended it a little ;-) – P Kuijpers Mar 04 '17 at 10:06

1 Answers1

32

I've found a different though simple approach that seems to work quite well. Animations for activities can also be performed using overridePendingTransition, so when the activity finishes you'll simply use that method.

It would be most effective to implement these overrides in a BaseActivity, which is extended by all activities in your project. Now all your activities will automatically include an exit animation and an animation when starting new activities:

public abstract class BaseActivity extends AppCompatActivity {

    @Override
    public void finish() {
        super.finish();
        onLeaveThisActivity();
    }

    protected void onLeaveThisActivity() {
        overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
    }

    // It's cleaner to animate the start of new activities the same way.
    // Override startActivity(), and call *overridePendingTransition*
    // right after the super, so every single activity transaction will be animated:

    @Override
    public void startActivity(Intent intent) {
        super.startActivity(intent);
        onStartNewActivity();
    }

    @Override
    public void startActivity(Intent intent, Bundle options) {
        super.startActivity(intent, options);
        onStartNewActivity();
    }

    @Override
    public void startActivityForResult(Intent intent, int requestCode) {
        super.startActivityForResult(intent, requestCode);
        onStartNewActivity();
    }

    @Override
    public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
        super.startActivityForResult(intent, requestCode, options);
        onStartNewActivity();
    }

    protected void onStartNewActivity() {
        overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
    }
}

To round things up, I'll include the 4 anim resources:

enter_from_right

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="100%p"
    android:toXDelta="0%p"/>

exit_to_left

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="0%p"
    android:toXDelta="-100%p"/>

enter_from_left

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="-100%p"
    android:toXDelta="0%p"/>

exit_to_right

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="0%p"
    android:toXDelta="100%p"/>

ps. You'd probably like to exclude the exit-animation in your starting / main activity ;-)

public class MainMenuActivity extends BaseActivity {
    ....
    @Override
    protected void onLeaveThisActivity() {
        // Don't use an exit animation when leaving the main activity!
    }
}

EDIT Oct 24 2019:

When navigating from one activity to the next, AND finishing the current activity in the process, take note that finish() should be called BEFORE the navigation implementation. If this is done in the wrong order, onLeaveThisActivity will be called AFTER onStartNewActivity, resulting in the wrong animation.

P Kuijpers
  • 1,593
  • 15
  • 27
  • 1
    Nice approach. I would update the answer to override startActivityForResult methods as well. – ikarhun Dec 24 '16 at 14:20
  • Great suggestion ikarhun, I'll try it out and update my code soon! – P Kuijpers Jun 10 '17 at 13:01
  • Nice solution. Only problem is that on a device that on my Samsung s6 that has this transition build in, it takes about twice as long to perform this animation compared to devices that don't have it. I created a post: https://stackoverflow.com/questions/45735395/activity-navigation-translation-animation-not-working-correctly-on-samsung-s6 – Rik van Velzen Aug 17 '17 at 12:42
  • @ikarhun when I was debugging activity transitions I found that when `startActivityForResult` is called, shortly afterwards `startActivity` is called too, so possibly the override isn't required. However, I'm not sure if this is always the case, and overriding it several times doesn't hurt – P Kuijpers Oct 24 '19 at 15:19