褪色的英雄在共享元素转换中看到了孩子

Wil*_*iam 11 android nested-views shared-element-transition

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

在标准共享元素转换中,在输入动画中,调用活动中的英雄视图会立即覆盖目标视图(在起始维度),然后转换动画在目标视图的维度中进行更改以到达其新位置.

但是,在返回动画上,返回活动的视图保留在叠加层的顶部,它们是在动画结束之前显示的视图,此时目标(调用活动的)英雄视图会捕捉到位.

如果两个英雄视图的内容存在任何差异,则会产生非常刺耳的效果 - 例如,线条换行的文本视图或完全不同的子视图.

与此同时,在Google Keep中,共享元素转换似乎在每个方向来回淡化内容视图,因此这种不和谐的效果相当不太明显.因此,填充或换行等方面的差异要小得多.

在我自己的应用程序中实现此功能的最佳方式是什么?

这是一个例子:

在此输入图像描述

Ben*_* P. 7

我的回答很长.它只提供了重新创建我在动画图像中看到的内容的一般框架,因此您需要花一些时间自己调整一下以使其完美.

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

tl; dr:"共享元素"只是绿卡/背景,因此您可以使用这些创建转换.在第二个活动的背景上放置绿色背景背后的灰色背景,以便绿色在其生长的同时绘制一些东西.将所有内容包装在父视图中,并将其设置alpha为淡入/淡出.

完整答案

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

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

让我们浏览每个文件,并谈谈我为实现预期结果所做的选择......

activity_main.xml中

这个非常简单.我刚建立了一个视图层次结构,模糊地类似于图像中的层次结构.View顶部的空白是a的占位符Toolbar,而Space卡片的底部只是为了使它更大一些.

activity_other.xml

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

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

MainActivity.java

另一个简单的课程.所有这一切Activity都是使卡片可以点击并设置过渡.

OtherActivity.java

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

shared_element_transition.xml

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

styles.xml

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

在此输入图像描述