I want to create an activity transition with shared elements like explained here.
I want the list items on the left to transform into the highlighted box on the right.
Well, that works great, but unfortunately the exit transition doesn't work at all. After I go back from the second activity, I get this:
The CardView just stays where it is and doesn't scale or transform anywhere. After a moment it fades out.
I thought the exit transition would be the enter transition played backwards but that doesn't seem to be the case here. How can I get the CardView to transform back into the ListItem on the left?
This is my current code:
In the OnItemClickListener of the first Activity
Intent intent = new Intent(context, DisplayEpisodeActivity.class);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,clickedRow.findViewById(R.id.background), "background");
startActivity(intent, options.toBundle());
My theme:
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="NewApi">
<style name="BaseTheme" parent="android:Theme.Material.Light.DarkActionBar">
<item name="android:colorPrimary">#D32F2F</item>
<item name="android:textColorPrimary">#616161</item>
<item name="android:colorPrimaryDark">#B71C1C</item>
<item name="android:colorAccent">#757575</item>
<item name="android:colorControlHighlight">#EF9A9A</item>
<item name="android:windowContentTransitions">true</item>
<item name="android:windowSharedElementEnterTransition">
@transition/change_image_transform</item>
<item name="android:windowSharedElementExitTransition">
@transition/change_image_transform</item>
</style>
</resources>
change_image_transform.xml:
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeTransform/>
<changeBounds/>
</transitionSet>
And I have set the transitionName
to the android.support.v7.widget.CardView
of the layout on the right and to the RelativeLayout
s on the left.
Both Activity and Fragment Shared transitions can be difficult to debug. The animations are fast by default, and sometimes the eye can only see "there is something wrong" but figuring out what/why can be non-trivial.
In debugging shared transition from A to B, I usually find VERY useful to Override onMapSharedElements
methods, so you can easily figure out which shared elements in A are being associated to elements in B. Something like this (inside B's onCreate()
method:
setEnterSharedElementCallback(new SharedElementCallback() {
@Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
Log.i(Constants.TAG, "EnterSharedElement.onMapSharedElements:" + sharedElements.size());
//manual override of non-working shared elements goes here
super.onMapSharedElements(names, sharedElements);
}
@Override
public void onRejectSharedElements(List<View> rejectedSharedElements) {
//Some element was rejected? Aha!!
Log.i(Constants.TAG, "EnterSharedElement.onMapSharedElements:" + rejectedSharedElements.size());
super.onRejectSharedElements(rejectedSharedElements);
}
@Override
public void onSharedElementEnd(List<String> sharedElementNames, List<View> sharedElements, List<View> sharedElementSnapshots) {
//AFTER the shared transition
super.onSharedElementEnd(sharedElementNames, sharedElements, sharedElementSnapshots);
}
});
}catch (Exception uie){
Log.e(Constants.TAG,"UIE:"+uie.getMessage());
}
In this way, it will be easier to figure out which elements are not being mapped (maybe they're simply not created yet) and to solve Shared transition issues (ie: glitches, artifacts)