Material Design 超炫过渡动画实现及流程分析(转)

转自:https://mp.weixin.qq.com/s/5B_txYTpOSXwMaQb4OikJg

作者博客

http://rkhcy.github.io

源码地址

https://github.com/Rkhcy/TransitionNote2

文章目录

    0. 概述

    1. Content Transition

        1.1. 使用

        1.2. 例子

        1.3. 具体流程

     2. ShareElement Transition

         2.1. 例子

         2.2. 具体流程

         2.3. 延迟加载

0

概述

在「Android 4.4.2引入的超炫动画库」中对于Transition的框架和常用的API使用进行了分析,Transition最常用的是在界面过渡方面,本文继续学习Transition在界面过渡上的使用。在界面过渡上,Transition分为不带共享元素的Content Transition和带共享元素的ShareElement Transition。1

Content Transition

先看下content transition的一个例子,在Google Play Games上的应用:

在经过学习后我们也可以设计出类似的效果,首先需要了解在界面过渡中涉及到的一些重要方法,从ActivtyA调用startActivity方法唤起ActivityB,到ActivityB按返回键返回ActivityA涉及到与Transition有关的方法

  • ActivityA.exitTransition()
  • ActivityB.enterTransition()
  • ActivityB.returnTransition()
  • ActivityA.reenterTransition()

因此,只要我们在对应的方法中设置了Transition就可以了。在默认没有设置对应Transition的情况下,Material-theme应用的exitTransition为null,enterTransition为Fade,如果reenterTransition和returnTransition未设定,则分别对应exitTransition和enterTransition。

使用

在style中添加android:windowContentTransitions 属性启用窗口内容转换(Material-theme应用默认为true),指定该Activity的Transition

也可以在代码中指定

然后启动Acticity

例子

这里在代码中指定ActivityA的exitTransition:

使用xml方式指定ActivityB的enterTransition:

运行效果如下:

上图动画有两个问题:

  1. ActivityA的exitTransition还没完全走完ActivityB的enterTransition就执行了,ActivityB的returnTransition还没完全走完ActivityA的reenterTransition就执行了;
  2. 状态栏和导航栏的动画不太协调;

问题1是因为默认情况下enter/return transition会比exit/reenter transition完全结束前稍微快一点运行,如果想让前者完全运行完后者再进来,可以在代码中调用Window的

或者在xml中设置

运行如下:

再看下问题2,默认情况下状态栏和标题栏也会参与动画(如果有导航栏也会,测试机默认木有导航栏),当我们把xxxoverlap属性设为false后就看得比较明显了,如果不想让它们参与动画通过excludeTarget()将其排除,在代码中:

或者在xml中:

效果如下:

具体流程

ActivityA startActivity()

  1. 确定需要执行exit Transition的target View
  2. Transition的captureStartValues()获取target View Visibility的值(此时为VISIBLE)
  3. 将target View Visibility的值设为INVISIBLE
  4. Transition的captureEndValues()获取target View Visibility的值(此时为INVISIBLE)
  5. Transition的createAnimator()根据前后Visibility的属性值变化创建动画

ActivityB Activity 开始

  1. 确定需要执行enter Transition的target View
  2. Transition的captureStartValues()获取获取target View Visibility的,初始化为INVISIBLE
  3. 将target View Visibility的值设为VISIBLE
  4. Transition的captureEndValues()获取target View Visibility的值(此时为VISIBLE)
  5. Transition的createAnimator()根据前后Visibility的属性值变化创建动画

2

ShareElement Transition

shareElement Transition的例子

shareElement Transition指的是共享元素从activity/fragment到其他activity/fragment时的动画

有了上面的分析看名字应该也猜得出方法对应的功能了,如果没有设置exit/enter shared element transitions,默认为 @android:transition/move,上面的Content Transition是根据Visibility的变化创建动画,而shareElement Transition是根据大小,位置,和外观的变化创建动画,如chanageBounds、changeTransform、ChangeClipBounds、 ChangeImageTransform等,具体API使用和效果可以参考上篇。指定shareElement Transition可以通过代码形式:

也可以通过xml形式:

然后启动Acticity

在布局文件中对于要共享的View添加android:transitionName且保持一致,如果要共享的View有点多,可以通过Pair,Pair<View,String> 存储着共享View和View的名称,使用如下

例子

在ActivityB的theme中添加SharedElementEnterTransition

change_image_transform.xml

执行效果:

具体流程

从图上看,好像图片是从一个ActivityA”传递”到另一个ActivityB,实际上真正负责绘制都发生在ActivityB上:

  1. ActivityA调用startActivity()后ActivityB处于透明状态
  2. Transition收集ActivityA中共享View的初识状态,并传递给ActivityB
  3. Transition收集ActivityB中共享View的最终状态
  4. Transition根据状态改变创建动画
  5. Transition隐藏ActivityA,随着ActivityB的共享View运动到指定位置,ActivityB的背景在ActivityA上淡入,并随着动画完成而完全可见。

我们可以通过修改Activity背景淡入淡出时间来验证,在ActivityB中加入

为了更直观,把ActivityA的exitTransition先注释掉,运行效果:

可以看到,ActivityB确实像盖在ActivityA上,这里用到了 ViewOverlay,原理简单来说就是在其他View上draw,共享View利用该技术可以实现画在其他View上。我们可以通过Window的setSharedElementsUseOverlay(false)来关闭该功能,不过这样一来会使最终结果和你预想的不一致,默认该值为true。

延迟加载

上面分析Transition会获取共享视图前后的状态值来创建动画,如果我们的图片是网上下载的,那么很有可能图片的准确大小需要下载下来才能确定,Activity Transitions API提供了一对方法暂时推迟过渡,直到我们确切地知道共享元素已经被适当的渲染和放置。在onCreate中调用postponeEnterTransition()(API >= 21)或者supportPostponeEnterTransition()(API < 21)延迟过渡;当图片的状态确定后,调用startPostponedEnterTransition()(API >= 21)或supportStartPostponedEnterTransition()(API < 21)恢复过渡,常见处理:

Thanks to

Material-Animations

Getting Started with Activity & Fragment Transitions (part 1-4)

What are all these dang Transitions

Shared Element Activity Transition

Define custom animations

Presentation-ContentTransition

You May Also Like

About the Author: ice.zhai

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注