Search code examples
androidandroid-animationonactivityresult

Calling startActivity with shared element transition from onActivityResult


I'm calling within onActivityResult

startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, imgv, imgv.transitionName).toBundle())

What I expect to happen
activityB to be started and displayed with a shared element transition

What actually happens
activityB is not started/displayed until minimizing the app and reopening it from recents (animation is also not displayed at this point). Without adding the scene transition it works per-usual and calling this from anywhere else in the code works as expected.

I've tried

  • runOnUiThread .
  • postponeEnterTransition() with startPostponedEnterTransition() in second activity.
  • finishAfterTransition() this results in a flicker and then showing activityB, I don't want to finish activityA but just tried this.
  • Using onActivityReenter() instead, I can't do this as it does not seem to be called when I startActivityForResult() in order to use google sign in.

I suspect it has something todo with a race condition with the animation framework


Solution

  • onActivityResult() is called between onStart() and onResume() for modern versions of the Android API. It sounds like there's a problem starting a new Activity with a shared element transition before your activity has resumed.

    (I'm not sure why this problem exists. Perhaps another user can answer that.)

    To work around this issue, I recommend saving information in onActivityResult() and then querying it in onResume():

    private boolean launchNextActivity = false;
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    
        if (...) {
            this.launchNextActivity = true;
        }
    }
    
    @Override
    protected void onResume() {
        super.onResume();
    
        if (launchNextActivity) {
            launchNextActivity = false;
            // do the launch
        }
    }