在具有共享元素的片段上执行转换会针对共享元素进行操作。

21

我正在使用新的棒棒糖API为片段设置 setEnterTransition, 然后为片段中的图像添加共享元素过渡。期望的行为是首先,图像应该移动到其位置,然后片段中的其余视图应该淡入。

然而,enterTransition被应用于共享元素,因此它与其余视图一起淡入。如果我不设置enterTransition,则图像会正确移动,但在它移动时其他内容已经可见。

我该如何使它不将enterTransition应用于共享视图?

我在AOSP中找到了这个提交,看起来应该解决这个问题,但似乎没有发挥作用。

这是示例代码:

public class Fragment1 extends Fragment {

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                           Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.main_fragment, container, false);
    final ImageView imageView = (ImageView) rootView.findViewById(R.id.image);
    final Button button = (Button) rootView.findViewById(R.id.button);

    button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        TransitionSet transitionSet = new TransitionSet();
        transitionSet.addTransition(new ChangeImageTransform());
        transitionSet.addTransition(new ChangeBounds());
        transitionSet.setDuration(300);

        Fragment fragment2 = new Fragment2();
        fragment2.setSharedElementEnterTransition(transitionSet);
        fragment2.setSharedElementReturnTransition(transitionSet);
        Fade fade = new Fade();
        fade.setStartDelay(300);
        fragment2.setEnterTransition(fade);

        getFragmentManager().beginTransaction()
            .replace(R.id.container, fragment2)
            .addSharedElement(imageView, "SharedImage")
            .commit();
      }
    });
    return rootView;
  }
}
1个回答

26

进入转换不应用于共享元素视图。最有可能的情况是你的共享元素位于另一个带有背景的视图中,使该视图受到进入转换的影响。这种情况如下所示:

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#FFF"
    >
    <ImageView android:src="@drawable/pretty_picture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:transitionName="picture"
        android:padding="20dp"/>
</FrameLayout>

这里,ImageView是共享元素。

如果发生这种情况,您需要添加一个神奇的转换:ChangeTransform。如果它检测到父级变化,它将从父级中提取共享元素并分别过渡。


2
George,我真想亲你!这解决了我的问题,我的视图在第二个片段中总是从屏幕顶部开始动画,而不是从它们在第一个片段中的位置开始。这是我的问题链接(有很多评论),谢谢!https://dev59.com/b18d5IYBdhLWcg3wVQ4U - brockoli
George,这是 ChangeTransform 最初的使用方式吗?还是它的具体实现只是恰好涵盖了这种情况?使用 ChangeTransform 看起来几乎是随意的,但却可以神奇地解决问题。为什么 ChangeBoundsChangeImageTransform 等没有被实现来涵盖这种情况呢? - Alex Lockwood
是的。过渡通常会动画化一小组属性,以便可以根据需要组合过渡。我们需要处理父级和子级分别转换的情况。由于这需要动画化相同的属性,因此我们必须合并看似不同的过渡。 - George Mount
@GeorgeMount,您能否详细说明一下答案?更改变换应该应用于共享元素还是其父元素? - Aadithya
@GeorgeMount 我有一个ImageView作为共享元素,但我没有像上面那样使用包装帧布局和ChangeTransform。一切都很顺利。我的问题是,在onTransitionEnd中,我尝试将我的ImageView设置为GONE,但它不起作用,我尝试调试并查看可见性标志仍然是VISIBLE。所以我尝试将我的ImageView放在FrameLayout中,并在FrameLayout上切换可见性更改,这样就可以工作了。有任何想法为什么会这样吗?谢谢 - Nhat Pham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接