Android Transitions

Transition

从Android 4.4 KitKat开始,有了Transitions API,在兼容包中也有Transitions API,因此可以在几乎所有的安卓设备上使用。

Transition API中,出现了诸如场景(Scene)、场景过渡(Transition)这样的概念,场景本质上是对ViewGroup的一层封装,描述了自己以及所有View对象的的状态。而过渡(Transition)则是一种这样的机制:读取不同场景之间View属性的变化,从而产生让这种变化看起来平滑的动画。

当一个场景改变的时候,transition主要负责:

(1)捕捉每个View在开始场景和结束场景时的状态。

(2)根据两个场景(开始和结束)之间的区别创建一个Animator。

Transition API提供的特色有:

组级别的动画:可以将整个View树作为整体动画,你只需指定ViewGroup,它的各个元素就会自动应用动画
内置动画:内置简单的动画,比如dissolution,darkening,resizing,movement等等。
对资源文件的支持:你可以不必写代码,在资源文件中创建动画。
回调:提供掌控动画过程的所有必要的回调方法。

缺点:

在那些不在UI线程中工作的View,比如SurfaceView或者TextureView中使用的时候不流畅。
AdapterView,比如ListView,当你需要针对列表中某个单独的元素使用动画的时候。
偶尔会在resize TextView的时候会出现同步的问题:在另一个对象的改变结束的之前,字体会提前出现在下一个场景中。

Activity的切换

首先在setContentView之前调用

1
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

或者在Activity对应的主题里设置

1
<item name="android:windowContentTransitions">true</item>

设置元素切换动画的方式

1
2
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>

销毁Activity

1
finishAfterTransition();

设置非共享元素的动画

  • (1)setExitTransition() - 当A start B时,使A中的View退出场景的transition

  • (2)setEnterTransition() - 当A start B时,使B中的View进入场景的transition

  • (3)setReturnTransition() - 当B 返回 A时,使B中的View退出场景的transition

  • (4)setReenterTransition() - 当B 返回 A时,使A中的View进入场景的transition

Content Transition

  • Activity A 调用startActivity().

    1.framework遍历A的View树,确定当A的exit transition运行时哪些view会退出场景(即哪些view是transitioning view)。

    2.A的exit transition捕获A中transitioning view的开始状态。

    3.framework将A中所有的transitioning view设置为INVISIBLE。

    4.A的exit transition捕获到A中transitioning view的结束状态。

    5.A的exit transition比较每个transitioning view的开始和结束状态,然后根据前后状态的区别创建一个Animator。Animator开始运行,同时transitioning view退出场景。

  • Activity B启动.

    1.framework遍历B的View树,确定当B的enter transition运行时哪些view会进入场景,transitioning view会被初始化为INVISIBLE。

    2.B的enter transition捕获B中transitioning view的开始状态。

    3.framework将B中所有的transitioning view设置为VISIBLE。

    4.B的enter transition捕获到B中transitioning view的结束状态。

    5.B的enter transition比较每个transitioning view的开始和结束状态,然后根据前后状态的区别创建一个Animator。Animator开始运行,同时transitioning view进入场景。

Fragment的切换

  • Content的exit, enter, reenter, 和return transition需要调用fragment的相应方法来设置,或者通过fragment的xml属性来设置。

  • 共享元素的enter和return transition也n需要调用fragment的相应方法来设置,或者通过fragment的xml属性来设置。

  • 在Fragment commit之前,共享元素需要通过调用addSharedElement(View, String) 方法来成为FragmentTransaction的一部分。

自定义Content Transition

可以借鉴Android中已有的实现Fade,Slide,Explode

Reveal

1
ViewAnimationUtils.createCircularReveal(View view,int centerX,  int centerY, float startRadius, float endRadius)