Return transition not working correctly when using fragment shared transitions
Asked Answered
R

1

20

I have 2 fragments ListMovieFragment and DetailMovieFragment.

I have an interface in ListMovieFragment that is implemented in the MainActivity. I am using shared element transition ; when I click the image view in ListMovieFragment the onMovieSelected is called in the MainActivity.

Transitioning from the ListMovieFragment works.
But when I click the back button, transitioning from the DetailMovieFragment to the ListMovieFragment fails to work.

gif of what is going wrong

Here is the MainActivity. I think I have got an incorrect combination for setting the transitions on the fragments.

public class MainActivity extends AppCompatActivity implements ListMovieFragment.MovieSelectedListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(savedInstanceState == null) {
            ListMovieFragment listMovieFragment = new ListMovieFragment();

            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.add(R.id.activity_main, listMovieFragment, ListMovieFragment.TAG);
            fragmentTransaction.commit();
        }
    }

    @Override
    public void onMovieSelected(int movieId) {
        DetailMovieFragment detailMovieFragment =
                (DetailMovieFragment)getSupportFragmentManager().findFragmentByTag(DetailMovieFragment.TAG);
        /* Create a new DetailMovieFragment if not exits */
        if(detailMovieFragment == null) {
            detailMovieFragment = new DetailMovieFragment();
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            /* Get the fragments that will be using the transition */
            ListMovieFragment listMovieFragment =
                    (ListMovieFragment)getSupportFragmentManager().findFragmentByTag(ListMovieFragment.TAG);
            if(listMovieFragment == null) {
                listMovieFragment = new ListMovieFragment();
            }

            /* Inflate the transition */
            Transition changeTransition = TransitionInflater
                    .from(MainActivity.this)
                    .inflateTransition(R.transition.change_image_transform);

            /* source fragment (ListMovieFragment) */
            listMovieFragment.setExitTransition(new Explode());
            listMovieFragment.setSharedElementReturnTransition(changeTransition);

            /* Destination fragment (DetailMovieFragment) */
            detailMovieFragment.setSharedElementEnterTransition(changeTransition);
            detailMovieFragment.setEnterTransition(new Explode());

            /* Get the shared imageview from the source fragment (MovieListFragment) */
            final ImageView ivSharedImage = (ImageView) findViewById(R.id.ivMoviePoster);

            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.activity_main, detailMovieFragment, DetailMovieFragment.TAG);
            fragmentTransaction.addToBackStack(DetailMovieFragment.TAG);
            fragmentTransaction.addSharedElement(ivSharedImage, getResources().getString(R.string.transition_poster_image));
            fragmentTransaction.commit();
        }
        else {
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.activity_main, detailMovieFragment, DetailMovieFragment.TAG);
            fragmentTransaction.addToBackStack(DetailMovieFragment.TAG);
            fragmentTransaction.commit();
        }
    }

    @Override
    public void onBackPressed() {
        if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
            getSupportFragmentManager().popBackStack();
        }
        else {
            super.onBackPressed();
        }
    }
}

My transition xml file:

<transitionSet>
    <changeBounds />
</transitionSet>

fragment_list

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingTop="18dp"
    android:paddingBottom="6dp">

    <ImageView
        android:id="@+id/ivMoviePoster"
        android:layout_width="184dp"
        android:layout_height="276dp"
        android:adjustViewBounds="true"
        android:scaleType="fitXY"
        android:transitionName="@string/transition_poster_image"/>
</LinearLayout>

fragment_detail

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="me.androidbox.fragmenttransitions.detail.DetailMovieFragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="The Movie App"
        android:textSize="28sp"
        android:fontFamily="sans-serif-light"
        android:textColor="@android:color/holo_blue_dark"/>

    <ImageView
        android:id="@+id/ivMoviePoster"
        android:layout_width="92dp"
        android:layout_height="138dp"
        android:layout_marginEnd="16dp"
        android:layout_marginTop="112dp"
        android:adjustViewBounds="true"
        android:scaleType="fitXY"
        android:layout_gravity="end"
        android:transitionName="@string/transition_poster_image"/>
</FrameLayout>

activity_main

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="me.androidbox.fragmenttransitions.activity.MainActivity">
</FrameLayout>
Rosecan answered 28/12, 2016 at 5:16 Comment(3)
It looks like transition works fine but we can't see the part outside poster's initial borders. What happens when you change first screens size or the poster's initial size?Kloster
Can you share your activity_main and fragment layouts?Thetes
@NileshSingh I have added the layout filesRosecan
K
10

You should change fragment_list.xml as below, android:layout_width/height properties are changed.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="18dp"
    android:paddingBottom="6dp">

    <ImageView
        android:id="@+id/ivMoviePoster"
        android:layout_width="184dp"
        android:layout_height="276dp"
        android:adjustViewBounds="true"
        android:scaleType="fitXY"
        android:transitionName="@string/transition_poster_image"/>
</LinearLayout>
Kloster answered 30/12, 2016 at 6:27 Comment(7)
I can't believe it was that simple. I thought I was doing something wrong with the transitions. Thanks.Rosecan
@Kloster I think the code works without this change. I don't see any other change than match_parent?Thetes
@Nilesh Singh It is about the layout size. If you have a bigger image or lots of images it would workKloster
@Kloster Bigger images?Thetes
@NileshSingh since the original layout decides it's width and height as "wrap content", if you have full-screen-size images you don't experience the problemKloster
I am using a 350x300 image and it works just fine with wrap_content.Thetes
I don't know about your situation maybe it is about the android API level?Kloster

© 2022 - 2024 — McMap. All rights reserved.