视图之间的共享元素转换(不是活动或片段)

Posted

技术标签:

【中文标题】视图之间的共享元素转换(不是活动或片段)【英文标题】:Shared Element Transitions Between Views (not Activities or Fragments) 【发布时间】:2015-04-07 19:30:33 【问题描述】:

假设我正在使用基于视图的方法来开发 android 应用程序,例如以下文章中所述:http://corner.squareup.com/2014/10/advocating-against-android-fragments.html

所以现在我有两个全屏视图。一个是可见的并且包含图像网格。另一个是隐藏的,是待点击图像的详细视图。在单击网格中的图像时没有过渡,网格视图将被隐藏并显示详细视图。现在,如果我想在网格视图中的小图像和细节视图中的大图像之间进行类似于共享元素的转换,该怎么办。这样的事情可能吗?

【问题讨论】:

android.transition.Scene ? 【参考方案1】:

是的,转换允许这样做。

在您的示例中,您的层次结构中已有网格视图和详细视图。要使用转换,如果详细视图不在视图层次结构中开始,它会更好地工作。你需要交换这两种观点。

有两种(相似的)方法可以做到这一点。第一个是在场景中有网格视图。然后使用 TransitionManager.go(detailScene, transition)。

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

让共享的观点有共同点很重要。通常它是 View 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);

【讨论】:

乔治,非常感谢您的回答!我使用您的方法 (github.com/eugenkiss/MaterialEverywhere/commit/…) 创建了一个快速 POC。但是,如果您将基于视图(共享)的过渡与原始的基于活动的过渡进行比较,那么您会发现一些缺点。例如,共享元素不是在叠加层上绘制的,而是在前一个场景上绘制的。您是否认为有可能改进这种方法,使其看起来(几乎)与之前基于活动的过渡完全一样? 我有一些好消息和一些坏消息。好消息是我想出了如何让你的应用程序转换工作。坏消息是它有点做作!淡入淡出过渡和 ChangeTransform 都将视图添加到叠加层。我不相信这些添加的顺序有任何保证。如果您反转将它们添加到集合中(先淡出,然后共享),它恰好可以工作。 transitionName 也被应用到了错误的元素(imageView 的容器),所以 ChangeImageTransform 无法处理它。 谢谢,它有效 (github.com/eugenkiss/MaterialEverywhere/commit/…)! 我建议检查这个库的转换:github.com/guerwan/TransitionsBackport 我喜欢这个答案,但这种转变在所有 android 设备上并不一致。可能的原因?

以上是关于视图之间的共享元素转换(不是活动或片段)的主要内容,如果未能解决你的问题,请参考以下文章

跨活动的片段之间的共享元素转换不一致

不同活动的片段之间的共享元素转换

共享元素转换:活动到嵌套在另一个活动中的片段

如何共享元素从片段到活动的过渡

共享元素转换在父片段和子片段之间不起作用(嵌套片段)

片段之间的共享元素转换