11

For shared element transition I am following this github project. It has 2 screens - one with recyclerview having number of cards & second the detail screen. As expected, it exhibits shared element transition of imageview & textview from recyclerview item to detail screen & reverse transition on back press.

But, if user changes orientation on detail screen, & then presses back button then the reverse transition animation doesn't work. Looking at this video's frames between 2:49 to 2:57 it seems to be possible even after orientation change. Any idea on this?

Edit:

Please check this video for better understanding.

Ankur
  • 602
  • 8
  • 24
  • What do you mean "the reverse transition animation doesn't work". What happens? Does the transition happen at all? Is there some sort of glitch? Do you have a video showing what happens? – Alex Lockwood Mar 13 '15 at 18:06
  • By reverse transition animation, I mean transition animation while going back from detail screen to main screen with recyclerview. If orientation is changed on detail screen, then pressing back just redirects to main screen without showing the imageview & textview actually moving from their detail screen position to their positions in main screen's recyclerview. – Ankur Mar 15 '15 at 16:04
  • Is your github project up to date? I recommend simplifying your project code as much as possible to determine the source of the problem (i.e. remove the producer stuff and any other necessary code and see if it still has the same problem). Then push the simplified updates to github. – Alex Lockwood Mar 16 '15 at 14:04
  • @AlexL The github link I had given was the project created by some other person which I am following. You can check my simplified project version [here](https://github.com/ankurwcities/Hero-Transition). – Ankur Mar 16 '15 at 14:24

4 Answers4

8

At last, I could fix this by applying separate theme to detail screen overriding following attribute value, but not sure why did this parameter change the animation behavior.

<item name="android:windowIsTranslucent">true</item>
Ankur
  • 602
  • 8
  • 24
  • 1
    This fixes it only partially. For me, the back animation coordinates are off. However, it's much better than without the android:windowIsTranslucent true. – GulBrillo Aug 26 '16 at 00:47
  • 1
    Actually, this is even broken in official Google apps (like Play Newsstand). – GulBrillo Aug 26 '16 at 00:57
  • 2
    I dont know how this works, i dont know how to find you. But i will find you, and i will thank you. – Sanket Berde May 07 '17 at 18:54
2

You have to set:

requestWindowFeature(Window.FEATURE_CONTENT_TRANSITIONS);
requestWindowFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);

in the calling and the called activity (MainActivity + NextActivity in this example).

I assume you open the NextActivity by calling:

ActivityOptions options = ActivityOptions.
      makeSceneTransitionAnimation(this, new Pair<View, String>(viewToAnimate, "animationName"));
Intent intent = new Intent(MainActivity.this, NextActivity.class);
startActivity(intent, options.toBundle());

In the NextActivity you have to add:

animatingView.setTransitionName("animationName");

If you do this the transition will work if you tap the back button.

BUT if you turn the device and press the back button it won't work.

To solve this problem i added this in the first activity (MainActivity in this example):

animatingView.setTransitionName("animationName");

The system now knows what to animate after a screen rotation.

Patrick Dorn
  • 756
  • 8
  • 13
  • 1
    `Window.FEATURE_CONTENT_TRANSITIONS` is not necessary for normal activity transitions. – Alex Lockwood Mar 13 '15 at 18:03
  • @PaMaDo As can be seen in github link in the question, I am already setting both window features as well as same transition name in both the activities. – Ankur Mar 15 '15 at 16:14
1

If you go into "Developer options" and enable "Don't keep activities", I think you'll find the problem will occur as well. In other words, the problem isn't that you are rotating the device... but more generally that the first activity is being destroyed while in the background.

Looking at your sample code, it looks like you're doing some weird stuff with an adapter (i.e. feeding the recycler view new grid items every 50ms from a background thread)? I can see why that might cause some issues for you... for example, what if the calling activity is destroyed and needs to be recreated immediately after the user clicks the back button and the return transition begins? If the shared element return transition begins and the desired shared element does not yet exist in the first activity (for example, because it has not yet been added by the adapter yet), the transition will not work properly.

I think this should probably be enough information to get you started solving the problem.

Alex Lockwood
  • 83,063
  • 39
  • 206
  • 250
  • I have not set "Don't keep activities" & I think that is the reason that it at least redirects me to main screen on back press, otherwise it would have destroyed the main screen itself as you have mentioned. Regarding adding views in background thread with some delay, same thing came in my mind first time & hence I already tried adding around 20 items in same main UI thread & without any delay, but the result was same, not showing transition animation on back press after orientation change. – Ankur Mar 15 '15 at 16:11
  • Does the transition work when you don't use a producer to add items to the adapter? – Alex Lockwood Mar 15 '15 at 17:45
  • Without using producer & hardcoding 20 items with same images & position number as text on TextView, results in same behavior. Animation doesn't work on back press after orientation change. Please check [this video](https://vid.me/LpEf) for better understanding. – Ankur Mar 16 '15 at 07:03
  • Consider using Android Studio to capture videos in the future: https://developer.android.com/tools/debugging/debugging-studio.html#screenCap – Alex Lockwood Mar 16 '15 at 11:38
1

I came across this same problem and this how I fixed it.

When the RecyclerView item is clicked, I pass the current position:

@Override
public void onItemClick(View sharedView, String transitionName, int position) {
    viewPosition = position;
    Intent intent = new Intent(this, TransitionActivity.class);
    intent.putExtra("transition", transitionName);
    ActivityOptionsCompat options = ActivityOptionsCompat.
            makeSceneTransitionAnimation(this, sharedView, transitionName);
    ActivityCompat.startActivity(this, intent, options.toBundle());
}

I save it in onSaveInstanceState to persist across configuration changes:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(VIEW_POSITION, viewPosition);
}

Then, in the onCreate method:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Workaround for orientation change issue
    if (savedInstanceState != null) {
        viewPosition = savedInstanceState.getInt(VIEW_POSITION);
    }

    setExitSharedElementCallback(new SharedElementCallback() {
        @Override
        public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
            super.onMapSharedElements(names, sharedElements);
            if (sharedElements.isEmpty()) {
                View view = recyclerView.getLayoutManager().findViewByPosition(viewPosition);
                if (view != null) {
                    sharedElements.put(names.get(0), view);
                }
            }
        }
    });
}

Cause of the problem: the sharedElements map was empty (I don't know why) after the orientation change.

Rúben Sousa
  • 1,389
  • 10
  • 8
  • Actually only this answer worked for me, but there is still a problem. If our recycler item is not visible on the screen, after orientation changed, shared element transition will not triggered. – HendraWD Aug 01 '17 at 03:58