在视图之间共享元素转换(不涉及活动或片段)

20
假设我正在使用基于视图的方法来开发Android应用程序,例如以下文章所述:http://corner.squareup.com/2014/10/advocating-against-android-fragments.html,现在我有两个全屏视图。一个是可见的,包含图像网格。另一个被隐藏起来,是将要点击的图像的详细视图。如果在网格视图中单击图像时不进行转换,则网格视图将被隐藏,详细视图将被显示。那么,如果我想在网格视图中的小图像和详细视图中的大图像之间实现类似于共享元素的过渡效果,这样的事情是否可能?

Image


2
android.transition.Scene? - pskink
1个回答

21

是的,使用过渡动画可以做到这一点。

在您的示例中,您已经将网格视图和详细视图放在了层次结构中。为了使用过渡动画效果更佳,最好让详细视图不要在视图层次结构中启动。您需要交换这两个视图。

有两种(类似的)方法可以实现这一点。第一种方法是将网格视图放在场景中。然后使用TransitionManager.go(detailScene, transition)。

第二种方法是使用TransitionManager.beginDelayedTransition,然后将详细布局与网格布局交换。

重要的是让共享的视图具有共同之处。通常是视图ID或transitionName。这种链接将告诉过渡系统,即使视图是不同的实例,它们也是关联的。

您需要使用的过渡动画是@android:transition/move。它结合了ChangBounds、ChangeTransform、ChangeImageTransform和ChangeClipBounds。您需要将其针对共享元素视图进行设置。看起来您将需要另一个过渡动画(例如:淡入淡出)用于进入和/或退出视图。

大致如下:

TransitionSet shared = ...
shared.addTarget("sharedName");
gridElement.setTransitionName("sharedName");
Fade fade = new Fade();
fade.excludeTarget("sharedName", true);
TransitionSet set = new TransitionSet();
set.addTransition(shared)
   .addTransition(fade);
TransitionManager.go(detailScene, set);

1
George,非常感谢您的答复!我使用了您的方法创建了一个快速POC(https://github.com/eugenkiss/MaterialEverywhere/commit/53b6ddcd22f40e06b11a06b9c7613a1e8b13ffe5)。但是,如果您将基于视图的(共享)过渡与原始基于活动的过渡进行比较,那么您会发现一些缺点。例如,共享元素没有在覆盖层上绘制,而是在之前的场景上。您是否看到改进这种方法的可能性,使其看起来(���乎)完全像以前基于活动的过渡? - Eugen
1
我有一些好消息和一些坏消息。好消息是我想出了如何使你的应用过渡效果正常工作。坏消息是它有点不专业!无论是淡入淡出还是ChangeTransform,都会向覆盖层添加视图。我不相信这些添加的顺序有任何保证。只有在将它们添加到集合中时反转(先淡入淡出,然后共享)才起作用。transitionName也被应用于错误的元素(imageView的容器),所以ChangeImageTransform不能对其起作用。 - George Mount
谢谢,它可以工作了(https://github.com/eugenkiss/MaterialEverywhere/commit/6599d6d42463710eb8422435ea7ef306360cf598)! - Eugen
我建议检查这个库的过渡效果:https://github.com/guerwan/TransitionsBackport - android developer
我喜欢这个答案,但是在所有的安卓设备上,这个过渡效果并不一致。可能的原因是什么? - GvSharma

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