12

我很好奇 android 如何在共享元素转换中处理英雄视图的子项,可以在 Google Keep 中看到:

在标准共享元素转换中,在进入动画中,调用活动中的主视图会立即与目标视图(在起始维度)重叠,然后转换动画目标视图维度的变化以到达新位置。

但是,在返回动画中,返回活动的视图仍保留在叠加层的顶部,并且它们是在动画结束之前显示的视图,此时目标(调用活动的)英雄视图会卡入到位。

如果两个英雄视图的内容有任何差异,这会产生相当不和谐的效果——例如,行换行方式不同的文本视图,或者完全不同的子视图。

同时,在 Google Keep 中,共享元素的过渡似乎使内容视图来回淡化,因此这种不和谐的效果相当不明显。因此,填充或换行等方面的差异问题要小得多。

在我自己的应用程序中实现这一点的最佳方式是什么?

这是一个例子:

在此处输入图像描述

4

1 回答 1

12

我的回答很长。而且它只提供了一个通用框架来重新创建我在您的动画图像中看到的内容,因此您必须花一些时间自己进行调整以使其完美。

代码在这里可见:https ://gist.github.com/zizibaloob/e107fe80afa6873301bf234702d4b2b9

tl; dr:“共享元素”只是绿卡/背景,因此您可以使用它们创建过渡。在第二个活动的绿色背景后面放置一个灰色背景,以便绿色在生长时可以在上面绘制。将您的所有内容包装在父视图中并为其设置动画alpha以淡入/淡出。

完整答案

在您的图像中,“共享元素”似乎是第一个屏幕上的绿卡/第二个屏幕的绿色背景。最重要的是,我们添加了两个额外的要求:

  • 第一个活动的灰色背景必须在过渡期间可见
  • 卡片的内容消失,然后在过渡期间/之后淡入

让我们浏览每个文件并讨论我为达到预期结果所做的选择......

activity_main.xml

这个真的很简单。我刚刚建立了一个视图层次结构,它与您图像中的视图层次结构隐约相似。View顶部的空白是 a 的占位符ToolbarSpace卡片底部的 只是为了让它更大一点。

activity_other.xml

此布局的相关部分是“父”视图的三重堆栈。他们每个人都有一个目的:

  • 顶层FrameLayout为卡片“增长”提供了灰色背景
  • 中间FrameLayout提供了将在活动之间共享的绿色背景
  • 内部LinearLayout包装了我们想要淡入/淡出的所有内容,并将由Activity类中的代码进行动画处理

MainActivity.java

另一个简单的类。所有这些Activity都是使卡片可点击并设置过渡。

其他活动.java

大多数魔法都发生在这里。在 内onCreate(),这些Toolbar东西都是标准的,所以我们可以跳过它。语句中的代码用于if设置淡入动画(包装在 an 中if,因此仅在首次启动时淡入)。我还重写onBackPressed()以反转淡入淡出动画并触发返回过渡。

shared_element_transition.xml

所有其余的魔法都在这个文件中。该<targets>元素不包括状态栏和导航栏,以确保它们在过渡期间不会闪烁。各种<changeFoo>标签是播放的实际过渡动画。

样式.xml

我将它包含在 Gist 中的唯一原因是TransitionTheme风格。这应用于OtherActivity清单中,它设置了我们的自定义转换(从shared_element_transition.xml)。

在此处输入图像描述

于 2017-10-31T22:14:08.463 回答