coderain blog

How to Animate Closing Transitions for External Activities in Android: Customizing Animations Beyond Your App

In Android, activity transitions play a pivotal role in shaping user experience (UX). Smooth, consistent animations make app interactions feel intuitive and polished. While Android provides built-in tools to animate transitions between your app’s own activities, customizing transitions involving external activities (e.g., launching the camera, gallery, or a web browser) is more challenging. External activities run in separate processes, and their exit animations are controlled by their own code or the system—leaving you with limited direct control when they close and return to your app.

This blog demystifies how to customize closing transitions for external activities. We’ll explore workarounds to override default system behavior, step-by-step implementation guides, and best practices to ensure your animations feel seamless and professional.

2025-12

Table of Contents#

  1. Understanding Activity Transitions in Android
  2. The Challenge with External Activities
  3. Prerequisites
  4. Methods to Customize Closing Transitions
  5. Step-by-Step Example: Custom Slide Transition
  6. Common Pitfalls and Troubleshooting
  7. Best Practices
  8. References

1. Understanding Activity Transitions in Android#

Before diving into external activities, let’s recap how transitions work for internal activities (activities within your app):

  • Enter/Exit Animations: When you launch a new activity, Android plays two animations:
    • enterAnim: The animation for the new activity entering the screen.
    • exitAnim: The animation for the current activity exiting the screen.
  • Reverse Animations: When the new activity finishes, the system reverses these animations: the new activity exits with the reverse of its enterAnim, and the original activity re-enters with the reverse of its exitAnim.

For internal activities, you control these animations using overridePendingTransition or ActivityOptions. However, external activities (e.g., ACTION_VIEW to open a URL) run in their own process, so you cannot directly modify their enterAnim or exitAnim.

2. The Challenge with External Activities#

External activities (e.g., the system camera, Chrome, or third-party apps) are not part of your app’s codebase. They:

  • Run in separate processes.
  • Use their own themes and animation logic.
  • Are controlled by the Android system, not your app.

When an external activity finishes, the system handles the transition back to your app. By default, this uses generic system animations (e.g., sliding right-to-left on older Android versions). To customize this, we need to manipulate how your app’s activity re-enters the screen or override the system’s default transition behavior.

3. Prerequisites#

To follow along, ensure you have:

  • Basic knowledge of Android development (Activities, Intents, XML layouts).
  • Familiarity with animation resources (XML view animations).
  • Android Studio (4.0+ recommended).
  • A test device or emulator running Android 4.0 (API 14) or higher (most methods work across all versions).

4. Methods to Customize Closing Transitions#

While you can’t control external activities directly, you can customize the transition when returning to your app using the following approaches:

Method 1: Using overridePendingTransition#

The simplest way to customize transitions for external activities is with overridePendingTransition, called immediately after startActivity() or startActivityForResult(). This method defines animations for:

  • The external activity entering the screen (when launched).
  • Your app’s activity exiting the screen (to launch the external activity).

Crucially, when the external activity finishes, the system plays reverse animations:

  • The external activity exits with the reverse of its enterAnim.
  • Your app’s activity re-enters with the reverse of its exitAnim.

By designing your exitAnim to reverse into your desired re-entry animation, you can control how your app appears when returning.

Syntax:

startActivity(intent) // Launch external activity
overridePendingTransition(enterAnim, exitAnim) 
  • enterAnim: Animation for the external activity entering (use 0 for no animation).
  • exitAnim: Animation for your activity exiting (reverse this to get your re-entry animation).

Method 2: Using ActivityOptions for Advanced Control#

For API 16+ (Android 4.1+), ActivityOptions provides more granular control over transitions. You can create a custom animation bundle and pass it to startActivity():

val options = ActivityOptions.makeCustomAnimation(
    context, 
    enterAnim, // External activity enter animation
    exitAnim   // Your activity exit animation
).toBundle()
 
startActivity(intent, options)

This works similarly to overridePendingTransition but is integrated with the AndroidX Activity Result API (recommended for modern apps).

Method 3: Theming and Window Animations#

You can also define default window animations in your app’s theme. This affects all activities, but you can override it dynamically for external activity launches:

  1. Define a custom style in res/values/styles.xml:

    <style name="CustomWindowAnimations">
        <item name="android:windowEnterAnimation">@anim/fade_in</item>
        <item name="android:windowExitAnimation">@anim/fade_out</item>
    </style>
  2. Apply the style to your activity dynamically before launching the external intent:

    window.setWindowAnimations(R.style.CustomWindowAnimations)
    startActivity(intent)
  3. Revert to the original theme afterward to avoid affecting other transitions.

5. Step-by-Step Example: Custom Slide Transition#

Let’s implement a slide transition where:

  • Your app’s activity slides out to the right when launching an external activity (e.g., a web browser).
  • When the external activity closes, your app’s activity slides in from the left.

Step 1: Create Animation Resources#

Create two XML animations in res/anim/:

slide_out_right.xml (your activity exits to the right):

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0%"
        android:toXDelta="100%"
        android:duration="300"/>
</set>

slide_in_left.xml (reverse of slide_out_right, for re-entry):

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="-100%"
        android:toXDelta="0%"
        android:duration="300"/>
</set>

Step 2: Launch External Activity with overridePendingTransition#

In your activity (e.g., MainActivity), launch the external intent and call overridePendingTransition:

// Button click to launch external activity (e.g., web browser)
btnLaunchExternal.setOnClickListener {
    val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com"))
    startActivity(intent)
    
    // Key: exitAnim = slide_out_right (reverse becomes slide_in_left on return)
    overridePendingTransition(0, R.anim.slide_out_right) 
}

How It Works:#

  • When launching the external activity:
    • enterAnim=0: No animation for the external activity entering.
    • exitAnim=slide_out_right: Your activity slides right to exit.
  • When the external activity finishes:
    • The system reverses exitAnim (slide_out_right → slide_in_left), so your activity slides left to re-enter.
    • The external activity exits with the reverse of enterAnim (0 → no animation).

6. Common Pitfalls and Troubleshooting#

  • overridePendingTransition Not Called Immediately: Always call it right after startActivity()/startActivityForResult(). Delaying it (e.g., in a post block) will prevent animations from playing.
  • Incorrect Animation Reversal: Ensure exitAnim is the reverse of your desired re-entry animation. For example, if you want a fade-in re-entry, use fade_out as exitAnim.
  • Device/Launcher Compatibility: Some launchers or OEM skins (e.g., Samsung, MIUI) may override system transitions. Test on multiple devices.
  • API Level Issues: ActivityOptions requires API 16+; use overridePendingTransition for older devices (API 1+).
  • Animation Resource Errors: Ensure animation XML files are in res/anim/ (not res/animator/, which is for property animations).

7. Best Practices#

  • Keep It Consistent: Align transitions with your app’s overall design language (e.g., Material Design guidelines).
  • Prioritize Performance: Use short durations (200–300ms) and avoid heavy animations (e.g., complex ObjectAnimator sequences).
  • Respect System Settings: Honor the user’s "Reduce Animations" accessibility setting by checking Settings.Global.getFloat() for animator_duration_scale.
  • Test Edge Cases: Verify transitions when the external activity is closed via back button, home button, or system dialogs.

8. References#

By leveraging overridePendingTransition, ActivityOptions, and careful animation design, you can create polished, custom transitions even for external activities. With these techniques, your app will feel cohesive and professional, enhancing the overall user experience.