Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared element transition don't have the expected behaviour

I implemented the shared element transition between from an image in a RecyclerView to an image in a new Fragment. The RecyclerView is hosted in a fragment hosted by an Activity and the target fragment is hosted inside another Activity.

When I click on my image, the transition is happening like expected and I get to my fragment. But when I click the back button, the transition is trying to put my image at the first position of my RecyclerView while it's currently displaying the image which is not necessarily the first one.

From this situation, I thought since it's a list of image in which I set a transition name inside the XML, maybe when going back, since all image has the same transition name, the process is confused and just get the first image with the given name. So maybe I should dynamically give a different transition name to each of them. I also set the same name to the target image and reset it every time a new image is selected. But it's still not working. Can anyone help me with that?

Here is the code inside my onItemClickListener:

mAdapter.setOnItemClickListener(new RssItemAdapter.OnItemCLickListener(){
    @Override
    public void onItemClick(View view, int position) {
        final RssItem item = mAdapter.getItem(position);
        final RssElementIntent intent = new RssElementIntent(getActivity(), item, position);
        // mRootView is the view of the fragment
        final ImageView image = (ImageView) 
mRootView.findViewById(R.id.rss_element_image);
        image.setTransitionName(getString(R.string.transition_name_rss_feed_picture) + position);
        ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
                        getActivity(), image, RssElementFragment.EXTRA_IMAGE);
        ActivityCompat.startActivity(getActivity(), intent, options.toBundle());
    }
});

Here is the code in the target fragment:

rssImage.setTransitionName(getString(R.string.transition_name_rss_feed_picture) + getArguments().getInt(ARG_ELEMENT_POSITION));
ViewCompat.setTransitionName(rssImage, EXTRA_IMAGE);

And here is the themes.xml :

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/theme_primary</item>
        <item name="colorPrimaryDark">@color/theme_primary_dark</item>
        <item name="android:colorAccent">@color/theme_accent</item>

        <!-- enable window content transitions -->
        <item name="android:windowContentTransitions">true</item>

        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>

        <!-- specify shared element transitions -->
        <item name="android:windowSharedElementEnterTransition">
            @transition/change_image_transform
        </item>
        <item name="android:windowSharedElementExitTransition">
            @transition/change_image_transform
        </item>

    </style>

Edit:

I found my error, I was getting the ImageView from the fragment rootView which was giving me a random ImageView from my RecyclerView, which mean the wrong transition name. So I used the view given by onItemClick and it worked! I also move the setTransitionName() inside the adapter.

mAdapter.setOnItemClickListener(new RssItemAdapter.OnItemCLickListener(){
        @Override
        public void onItemClick(View view, int position) {
            final RssItem item = mAdapter.getItem(position);
            final RssElementIntent intent = new RssElementIntent(getActivity(), item, position);
            // WRONG !
            // final ImageView image = (ImageView) mRootView.findViewById(R.id.rss_element_image);
            // Correct
            final ImageView image = (ImageView) view.findViewById(R.id.rss_element_image);

            ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
                            getActivity(), image, RssElementFragment.EXTRA_IMAGE);
            ActivityCompat.startActivity(getActivity(), intent, options.toBundle());
        }
    });
like image 307
lcw_gg Avatar asked Feb 05 '15 08:02

lcw_gg


1 Answers

I found my error, I was getting the ImageView from the fragment rootView which was giving me a random ImageView from my RecyclerView, which mean the wrong transition name. So I used the view given by onItemClick and it worked! I also move the setTransitionName() inside the adapter.

mAdapter.setOnItemClickListener(new RssItemAdapter.OnItemCLickListener(){
        @Override
        public void onItemClick(View view, int position) {
            final RssItem item = mAdapter.getItem(position);
            final RssElementIntent intent = new RssElementIntent(getActivity(), item, position);
            // WRONG !
            // final ImageView image = (ImageView) mRootView.findViewById(R.id.rss_element_image);
            // Correct
            final ImageView image = (ImageView) view.findViewById(R.id.rss_element_image);

            ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
                            getActivity(), image, RssElementFragment.EXTRA_IMAGE);
            ActivityCompat.startActivity(getActivity(), intent, options.toBundle());
        }
    });
like image 166
lcw_gg Avatar answered Oct 15 '22 06:10

lcw_gg