Animate ImageView between two activities using shared element transitions with ChangeImageTransform

25,591

Solution 1

To make a screen transition animation between two activities that have a shared element, you can read this article and follow the mentioned steps:

  1. Enable window content transitions in your theme.
  2. Specify a shared elements transition in your style.
  3. Define your transition as an XML resource.
  4. Assign a common name to the shared elements in both layouts with the android:transitionName attribute.
  5. Use the ActivityOptions.makeSceneTransitionAnimation() method.

About the 3rd step, according to the documentation:

In combination with ChangeBounds, ChangeImageTransform allows ImageViews that change size, shape, or ImageView.ScaleType to animate contents smoothly.

The res/transition/your_transition.xml should be like this:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds>
        <targets>
            <target android:targetId="@id/ivA" />
            <target android:targetId="@id/ivB" />
        </targets>
    </changeBounds>
    <changeImageTransform>
        <targets>
            <target android:targetId="@id/ivA" />
            <target android:targetId="@id/ivB" />
        </targets>
    </changeImageTransform>
</transitionSet>

or simply like this if only ivA and ivB need to be animated:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds/>
    <changeImageTransform/>
</transitionSet>

Solution 2

I have got this working following this guide, a few others, and the referenced material.

A transition set in this style. I put this under res/transition:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds>
        <targets>
            <target android:targetId="@id/ivA" />
            <target android:targetId="@id/ivB" />
        </targets>
    </changeBounds>
    <changeImageTransform>
        <targets>
            <target android:targetId="@id/ivA" />
            <target android:targetId="@id/ivB" />
        </targets>
    </changeImageTransform>
</transitionSet>

In the source and target ImageViews, you need to add a name tag. The name must be the same.

<ImageView
...
android:transitionName="MYTRANSITIONVIEW"

/>

In styles.xml, add to the application theme:

<item name="android:windowContentTransitions">true</item>
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowSharedElementEnterTransition">@transition/my_transition</item>
<item name="android:windowSharedElementExitTransition">@transition/my_transition</item>

I am running this inside a fragment so I start the new activity like this:

Bundle bundle = null;

if (activity != null) {
    ActivityOptionsCompat options =
                ActivityOptionsCompat.makeSceneTransitionAnimation(activity, Frag2_, "MYTRANSITIONVIEW");
    bundle = options.toBundle();
}
activity.startActivity(i, bundle);

It works on API 21 clients. It did not work on an API 16 client as the XML tags are not valid.

I hope this helps.

Slight update, to get the reverse transition on exit, I had to call

supportFinishAfterTransition();

rather than finish();

Share:
25,591
iForests
Author by

iForests

Hi.

Updated on July 09, 2022

Comments

  • iForests
    iForests almost 2 years

    I am trying to animate one ImageView to another position between two activities in Android API level 21. Since "MoveImage" in Android L Preview has been removed, I use "ChangeImageTransform" instead, but the sample code in documents doesn't work out (the two images animated separately).

    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
        <changeImageTransform>
            <targets>
                <target android:targetId="@id/ivA" />
                <target android:targetId="@id/ivB" />
            </targets>
        </changeImageTransform>
    </transitionSet>
    

    Is there any working example? Thanks!

  • Timothy Logan
    Timothy Logan over 9 years
    I've been trying to get this to work, but the enter transition for the new activity fades in with the ImageView being the last thing showing in the old activity. The exit transition works though.
  • Yi-Ping Shih
    Yi-Ping Shih over 9 years
    @TimmahhTimmahh Did you follow all the steps in the document? Please provide more information, thank you :)
  • Timothy Logan
    Timothy Logan over 9 years
    I found out what was going on. I was adding the view to a ListView header so it couldn't be found until after the transition. The solution was to postpone the transition and then start it in an OnPreDrawListener of the ListView.
  • WitaloBenicio
    WitaloBenicio over 9 years
    Hi, i tried to use that in my application but when i click in a item of my list the image of the list go to the other application (that would be to get bigger) but it remains the same size. If a press the back button, the image goes to the right size and returns to the list.
  • EvilDuck
    EvilDuck almost 9 years
    @Radu, why can't someone just figure it out?
  • Sandip Fichadiya
    Sandip Fichadiya over 8 years
    it should't be res/transitions, it should be res/transition :)
  • Tooroop
    Tooroop about 8 years
    @TimmahhTimmahh solution works for me. I see the exit animation but not the enter animation. You can check the solution here: androiddesignpatterns.com/2015/03/…
  • fanjavaid
    fanjavaid over 6 years
    What is <changeImageTransform/>? Cause when i remove it, my transition just works fine
  • Diego Ricardo Valdivia Arreola
    Diego Ricardo Valdivia Arreola about 5 years
    The information in the link provided is deprecated, here is the updated version: developer.android.com/training/transitions/…