在动画

时间:2017-06-19 22:58:01

标签: android animation android-animation android-transitions shared-element-transition

我有许多共享元素,我正在通过ActivityOptions.makeSceneTransitionAnimation在两个活动之间转换。当我输入第二个活动时,我想确定ImageView的最终目标尺寸,以便我可以设置ImageView的适当宽度。我相信这样做会让对象(它也是一个共享元素)能够顺利过渡。

ImageViewfitStart scaleType,具有固定的高度和wrap_content宽度。图像将被动态加载并从第一个活动缩小到第二个活动,所以我不知道最终的宽度。在转换开始之前,我想设置ImageView的{​​{1}}宽度,以匹配转换结束后的最终宽度。

目前,此LayoutParams的{​​{1}}属性导致其右侧的元素无法知道其最终放置位置的位置,因此它在到达之前会从屏幕向右移动返回并降落在正确的位置。

这是动画的GIF。第一个元素是wrap_content,动画正确,第二个元素是ImageView右侧的按钮:

enter image description here

请注意,当第二个活动返回到第一个活动时,第二个元素会平滑过渡到屏幕左侧,因为结束位置已知。

当我向ImageView提供特定宽度(例如ImageView而不是ImageView时(然后在转换完成后将其更改回100dp),Second Element移动更多顺利到最后的休息处,但由于wrap_content将被动态加载和缩放,我不会事先知道XML中图像的真实宽度,所以当我在第二个元素时总会有一个不稳定的运动转换后将其更改为wrap_content

enter image description here

所以我想确定ImageView的目标宽度,并在第二个活动的转换开始之前以编程方式设置它,以便第二个元素知道它需要向左走多远。我曾尝试使用wrap_contentImageView,但我不知道如何获得ImageView转换到的最终宽度。

我可以在第二个活动的ViewTreeObserver中调用哪些内容来确定ImageView在转换后最终会达到什么宽度?

修改

我尝试了this answer中的解决方案,但它报告了ImageView的开始宽度,而不是它转换到的最终宽度。作为参考,这些是我正在切换的两个活动的布局: enter image description here

请注意,我正在移动并缩小ImageView。

我调整了答案的代码,因为我没有使用支持库,因此必须在TransitionValues调用中移至onCreate以避免imageView.getViewTreeObserver()

onPreDraw()

日志报告的宽度为998,这是活动1中imageView的较大尺寸(转换前的起始大小)。所以第二元素仍然在屏幕上飞行。

现在我已经有了这个代码,我可以使用较大图像的宽高比信息来计算出较小图像的最终宽度,因为我知道最终的高度,但是{{{ 1}} scaleType?

知道Android是否能告诉我共享元素定位的最终大小真是太好了。

1 个答案:

答案 0 :(得分:3)

情况就是如此:如果您将资源从@drawable/first_element更改为@drawable/first_element_thumb,则您将无法长时间体验该行为。缺点是,每次转换开始时你都会看到一个小故障,那是因为在转换开始之前,drawable正在从高分辨率变为低分辨率。

这是300ms的动画时间:

enter image description here

这是5000ms的动画时间:

enter image description here

如果您希望转换没有这个故障,那么解决方案是从高分辨率可绘制开始转换,并在转换视图时将可绘制替换为低分辨率。您可以在Nick Butcher中看到"Animatable" talk描述该功能。您最终会编写自定义转换类,如this one