使用片段共享过渡时返回过渡无法正常工作

Posted

技术标签:

【中文标题】使用片段共享过渡时返回过渡无法正常工作【英文标题】:Return transition not working correctly when using fragment shared transitions 【发布时间】:2017-05-12 08:46:03 【问题描述】:

我有 2 个片段 ListMovieFragmentDetailMovieFragment

我在ListMovieFragment 中有一个在MainActivity 中实现的接口。我正在使用共享元素转换;当我单击ListMovieFragment 中的图像视图时,onMovieSelected 会在MainActivity 中调用。

ListMovieFragment 工作过渡。 但是当我单击 back 按钮时,从 DetailMovieFragment 转换到 ListMovieFragment 失败。

这里是 MainActivity。我认为我在片段上设置过渡的组合不正确。

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();
        
    

我的过渡 xml 文件:

<transitionSet>
    <changeBounds />
</transitionSet>

片段列表

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

    <ImageView
        android:id="@+id/ivMoviePoster"
        android:layout_
        android:layout_
        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_
    android:layout_
    tools:context="me.androidbox.fragmenttransitions.detail.DetailMovieFragment">

    <TextView
        android:layout_
        android:layout_
        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_
        android:layout_
        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_
    android:layout_
    tools:context="me.androidbox.fragmenttransitions.activity.MainActivity">
</FrameLayout>

【问题讨论】:

看起来过渡效果很好,但我们看不到海报初始边框之外的部分。当您更改第一个屏幕尺寸或海报的初始尺寸时会发生什么? 你能分享一下你的activity_main和fragment布局吗? @NileshSingh 我已经添加了布局文件 【参考方案1】:

您应该如下更改fragment_list.xmlandroid:layout_width/height 属性已更改。

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

    <ImageView
        android:id="@+id/ivMoviePoster"
        android:layout_
        android:layout_
        android:adjustViewBounds="true"
        android:scaleType="fitXY"
        android:transitionName="@string/transition_poster_image"/>
</LinearLayout>

【讨论】:

我不敢相信它这么简单。我以为我在过渡方面做错了什么。谢谢。 @cokceken 我认为代码无需此更改即可工作。除了 match_parent,我没有看到任何其他变化? @Nilesh Singh 这与布局大小有关。如果您有更大的图像或大量图像,它会起作用 @cokceken 图片更大? @NileshSingh 因为原始布局将其宽度和高度决定为“包装内容”,如果您有全屏尺寸的图像,您不会遇到问题

以上是关于使用片段共享过渡时返回过渡无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

共享元素返回过渡不适用于片段中的 recyclerview 和 cardview

片段之间的共享元素转换

如何实现与视频的共享元素过渡

CSS 过渡无法正常工作

隐藏div时,过渡在vue上无法正常工作

自定义水平弹出过渡无法正常工作