为View的切换添加过渡动画

  动画效果不仅可以使得应用更加吸引人,更可以突出变化的内容,使得用户能够更好地理解应用的操作和运作方式。Android提供了Transitions Framework来为View层级之间的切换添加过渡效果,最低需要API level 19。下面通过一个例子说明如何 添加过渡动画。

  例子以在Android上实现Master/Detail Flow为基础,最终实现效果如下:

1. 添加Transition

1.1. 添加transitionSet

  transitionSet包含了一组动画效果。新建/res/transition-v21/文件夹,不在低于Android L的版本上显示动画。

  在/res/transition-v21下新建detail_window_enter_transition.xml,设置用于显示进入MovieDetailActivity(Detail页面)的过渡效果:

这里 android:duration 为动画持续时间,单位为毫秒。 <fade> 表示淡入效果, <targets> 用于指示动画作用的目标,这里用 android:excludeId 排除了状态栏和底部虚拟按钮。 <slide android:slideEdge="top"> 表示滑入动画,滑入方向为上方,作用于 app_bar 。

【完整代码】

  类似地,新建detail_window_return_transition.xml,设置退出MovieDetailActivity(Detail页面)的过渡效果:

【完整代码】

1.2. 设置Theme

  为了启用过渡效果,需要在Activity的Theme中设置 android:windowContentTransitions 为 true ,并指明所使用的transitionSet。这里的例子使用了Master/Detail Flow,为MovieGridActivity(Master页面)设置主题 AppTheme.Main ,为MovieDetailActivity(Detail页面)设置主题 AppTheme.Detail 。

【完整代码】

  在/res/values-v21/styles.xml中为过渡前后的两个Activity打开 android:windowContentTransitions ,并为MovieDetailActivity(Detail页面)的主题 AppTheme.Detail 指定transitionSet:

【完整代码】

  在/res/values/styles.xml中依然需要定义 AppTheme.Main 和 AppTheme.Detail ,在Android L之前版本上不显示过渡动画:

【完整代码】

1.3. 启动Activity

  最后,使用ActivityOptionsCompat通过ActivityCompat来启动Activity,过渡动画就会在进入Detail Activity时播放。

2. 添加Shared Element Transition

  如果切换前后的两个界面具有相同的元素,那么可以使用Shared Element Transition为相同元素添加过渡效果。在这个例子中,MovieGridActivity(Master页面)和MovieDetailActivity(Detail页面)都具有电影海报这个元素,下面为电影海报添加Shared Element Transition。

2.1. 指定transitionName

  首先参考1.2.中的步骤,在Activity的Theme中设置 android:windowContentTransitions 为 true 。

  然后需要为Master Activity和Detail Activity中用于显示电影海报的ImageView添加transitionName,将这两个ImageView关联起来。首先定义transitionName的字符串:

  MovieGridActivity(Master页面)的电影海报位于/res/layout/item_movie.xml:

【完整代码】

  MovieDetailActivity(Detail页面)的电影海报位于/res/layout/fragment_movie_detail.xml:

【完整代码】

2.2. 启动进入和返回动画

  依旧用ActivityOptionsCompat通过ActivityCompat来启动Activity,这时需要在ActivityOptionsCompat中指明过度前后所共享的View(显示电影海报的ImageView),以及共享元素的名称(即之前设置的transitionName)。

【完整代码】

  然后还需要设置从MovieDetailActivity(Detail页面)返回MovieGridActivity(Master页面)的动画,在MovieDetailActivity中设置按下返回按钮时,调用 supportFinishAfterTransition() :

【完整代码】

3. 延迟过渡动画

  有时候在进行切换时,切换的目标元素还未载入完成,由此到会导致动画的不连贯。所以需要通过 supportPostponeEnterTransition() 在MovieDetailActivity刚创建时,延迟动画效果,此时就算在MovieGridActivity(Master页面)的电影列表中点击了电影,画面会暂停,不会触发过渡动画:

  在这个例子中,MovieDetailFragment中的数据由MovieGridActivity传递,耗时的操作在于MovieDetailActivity中下载背景图片。应当在图片下载并显示完成后,无论成功与否,都启动动画效果,防止卡死:

【完整代码】

4. 完整代码

  完整代码可以参考这里