共享元素动画只知道很炫酷,却不知道其原理,网上也没什么资料,今天看下其中的源代码。

android 共享 动画 安卓共享元素动画_android 共享 动画

首先是这么写,那么看startActivity带的Bundle什么作用

android 共享 动画 安卓共享元素动画_宽高_02

Context里面是一个抽象方法,而且options只能用系统的ActivityOptions,都没法自定义。。

既然我们大部分都是通过Activity进行跳转的,那么直接看Activity对这个方法的实现

android 共享 动画 安卓共享元素动画_android_03

接着往下走

android 共享 动画 安卓共享元素动画_赋值_04

对于上面的mParent,具体看

这里不详述,基本上都是null

那么第一行是针对options做了一个包装,具体代码:

android 共享 动画 安卓共享元素动画_矩阵变换_05

第二句即执行startactivity操作

android 共享 动画 安卓共享元素动画_矩阵变换_06

可惜今天重点不是这里,相关东西大家可以自行到网上查阅

android 共享 动画 安卓共享元素动画_android 共享 动画_07

可以看到,到了这里就是执行退出动画了

android 共享 动画 安卓共享元素动画_android 共享 动画_08

到了startExit就是最最重要的部分了

android 共享 动画 安卓共享元素动画_矩阵变换_09

为什么能过渡得这么自然,moveSharedElementsToOverlay就是精华

这里可以参考下面这个链接里兄台的分析


总结一下,就是将共享元素复制到顶层View的Overlay中,然后再在overlay进行动画,等动画结束后再将界面的visibility设置成可见与不可见。

那么上面代码中的mActivity是什么呢?通过查找mActivity赋值的地方:

注释写得很清楚,在makeSceneTransitionAnimation的时候创建的,也就是跳转下个activity创建options的时候创建的,用于从下个activity返回的时候执行返回动画使用。

那么本文最最精彩的部分来了,如果说两个activity的shareElements不一样的话会有什么后果呢?(应该没人像我这么蛋疼。。)

如图可见,一个设置的是子条目中的imageview,一个设置的是下一个页面的banner,然后makeSceneTransitionAnimation的时候传入的是整个item的view,那么看看有什么效果

android 共享 动画 安卓共享元素动画_宽高_10

可以很明显得看到,共享元素是对的,就是单个图片,但是转场动画的位置和大小是不对的,因为使用bindingview的关系,我是针对整个子item进行触发的点击事件,代码如下

android 共享 动画 安卓共享元素动画_赋值_11

所以在从activity B回到activity A进行动画的时候,可以看到,整个子条目的可见性都是invisible的,而banner上的图片也是从banner的大小缩小成了子条目的高度(但维持图片宽高比)

由此,我们可以得出结论:

shareElement所对应的view是添加了transitionName的view,而makeSceneTransitionAnimation的时候传入的view是决定整个动画宽高,以确定执行动画时的matrix矩阵变换后的的具体值。

完结撒花!

本文分析应该是有不对的地方,希望大家能够指出