Android转换三个片段之间的共享元素

时间:2016-01-12 15:32:49

标签: android android-fragments android-transitions shared-element-transition

我正在尝试使用共享元素在片段之间实现一些不错的过渡,这就是我想要实现的目标:

enter image description here

当我从片段1 切换到片段2 时:

  • 片段1 淡出
  • 徽标向左上方移动
  • 片段2 来自底部。

当我从片段2 切换到片段3 时:

  • 片段2 淡出
  • 徽标“不动”
  • 标题1 向左移动
  • 标题2 来自右侧
  • 片段3 来自底层

以下是片段1 的设置:

Fagment1.java:

fragment.setExitTransition("fade"); //parameter shortened for readability

XML:

<ImageView [...]
    android:id="@+id/octopuss"
    android:transitionName="@string/octopuss"/>

以下是片段2 的设置:

Fragment2.java:

fragment3.setEnterTransition("slide_bottom");
fragment3.setSharedElementEnterTransition("move");
fragment3.setExitTransition("fade");

XML:

<ImageView [...]
    android:transitionName="@string/octopuss"/>

<TextView [...]
    android:transitionName="title1"
    android:id="@+id/title1" />

在活动中调用片段2:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction()
    .replace(R.id.fullscreen_content, fragment2)
    .addToBackStack("connection_transaction");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)     
    ft.addSharedElement(findViewById(R.id.octopuss), getString(R.string.octopuss));
ft.commit();

以下是片段3 的设置:

Fragment3.java:

fragment3.setEnterTransition("slide_bottom");
fragment3.setSharedElementEnterTransition("slide_right");

XML:

<ImageView [...]
    android:transitionName="@string/octopuss"/>

<TextView [...]
    android:transitionName="title1"/>

在活动中调用fragmen 3:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction()
    .replace(R.id.fullscreen_content, fragment3)
    .addToBackStack("preferences_transaction");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    ft.addSharedElement(findViewById(R.id.title1), "title1");
ft.commit();

片段1 片段2 之间的每次转换都非常有效。

但是当我要求片段3 时,每个片段都会启动它的enterTransition \ exitTansition,就像它们根本没有共享元素一样:

  • 标题1淡出片段2
  • 标题2来自底部,片段3

有人可以帮我找到原因吗?我错过了什么?

1 个答案:

答案 0 :(得分:1)

这变成了一个冗长的答案:解释为什么它不起作用以及如何使它发挥作用。

问题

我认为这里有一些混淆,关于什么构成共享元素以及它们如何工作。

请记住,基本思路是您从一个屏幕(活动或片段)移动到另一个屏幕,并且共享元素表示两者都存在的内容。为了保持连续性和更平滑的过渡,您希望该项目从第一个屏幕上的位置平滑地更改为第二个屏幕上的位置。

共享元素只是一个在转换过程中独立于布局其余部分移动的项目。

所有这一切;在此示例中,大型中央徽标更改为角落中的小徽标的第一个转换是共享元素转换的一个很好的示例。

第二个不是真正的共享元素转换。 我不确定行fragment3.setSharedElementEnterTransition("slide_right");包含哪一行(我认为你为了清楚起见缩写了它)但我怀疑它在你的应用程序运行时被忽略,因为它不是一个有效的共享元素转换。

告诉共享元素“向右滑动”是没有意义的,因为根据定义,元素移动的方向取决于其对应的位置;它会移动那里,无论发生什么方向。

标题1和标题2之间的实际共享元素转换看起来并不多,因为它们在同一个地方的大小相同,它们只会停留在那里。

一切都没有丢失

使用共享元素转换使这项工作的方法是将标题1和标题2放在两个片段中,并添加两个共享元素。在一个片段中,标题1将处于正常位置,标题2将隐藏在屏幕的右侧。在另一个标题2中将处于正常位置,标题1将隐藏在屏幕左侧。

对于屏幕外的TextView,请使用android:translationX="-86dp"(或其他一些数字将其放置在屏幕的左侧或右侧)。

需要注意的事项:只有在运行应用时,才能在布局预览中看到translationX属性的效果。

确保为title1和title2匹配适当的transitionNames。