共享元素转换没有预期的行为

lcw*_*_gg 7 android android-fragments android-5.0-lollipop shared-element-transition android-recyclerview

我实现了从RecyclerView中的图像到新Fragment中的图像之间的共享元素转换.RecyclerView托管在由Activity托管的片段中,目标片段托管在另一个Activity中.

当我点击我的图像时,过渡就像预期的那样发生,我进入了我的片段.但是,当我单击后退按钮时,转换尝试将我的图像放在我的RecyclerView的第一个位置,而它当前正在显示不一定是第一个的图像.

从这种情况来看,我认为因为它是一个图像列表,我在其中设置了XML内的转换名称,也许在返回时,因为所有图像都具有相同的转换名称,所以该过程混淆并且只获得给定的第一个图像名称.所以也许我应该动态地给每个人提供一个不同的过渡名称.我还为目标图像设置了相同的名称,并在每次选择新图像时重置它.但它仍然无法正常工作.任何人都可以帮助我吗?

这是我的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());
    }
});
Run Code Online (Sandbox Code Playgroud)

以下是目标片段中的代码:

rssImage.setTransitionName(getString(R.string.transition_name_rss_feed_picture) + getArguments().getInt(ARG_ELEMENT_POSITION));
ViewCompat.setTransitionName(rssImage, EXTRA_IMAGE);
Run Code Online (Sandbox Code Playgroud)

这是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>
Run Code Online (Sandbox Code Playgroud)

编辑:

我发现了我的错误,我从片段rootView获取了ImageView,它从我的RecyclerView给了我一个随机的ImageView,这意味着错误的转换名称.所以我使用onItemClick给出的视图,它工作了!我也移动setTransitionName()适配器内部.

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());
        }
    });
Run Code Online (Sandbox Code Playgroud)

lcw*_*_gg 9

我发现了我的错误,我从片段rootView获取了ImageView,它从我的RecyclerView给了我一个随机的ImageView,这意味着错误的转换名称.所以我使用onItemClick给出的视图,它工作了!我还在适配器中移动setTransitionName().

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());
        }
    });
Run Code Online (Sandbox Code Playgroud)