简介
android 5.0
之后推出了Material Design(设计材料),不单从UI上带来了更好的视觉美感和用户体验,其中Activity Transition是Material Design中提供的一种动画效果。它通过运动和切换不同状态之间的元素来产生各种动画效果。
transition动画实现的前提条件:minSdkVersion 21
启动方式
5.0版本以下,一般通过两种方式来实现界面的切换动画。
1.配置Activity的主题,style中的windowEnterAnimation和windowExitAnimation设置动画。
2.调用overridePendingTransition(enterAnim,exitAnim)方法,但使用该方法的坑比较多。
如果android系统在2.0以上,手机动画效果已开启,用此方法仍然没有看到效果,注意以下几点:
a.在startActivity(intent)之后使用时,enterAnim在exitAnim上层(图层的上一层)执行(即进入的动画在上层),此时可以没有exitAnim,但是一定要有enterAnim
如果enterAnim传0或者无效的动画资源的话,进入时没有动画效果,新页面会在一瞬间覆盖屏幕,所以exitAnim不会被看见,即使它执行了,你也丝毫看不见。
b.在finish()之后使用时,enterAnim在exitAnim下层执行(出去的动画在上层),此时可以没有enterAnim,但是一定要有exitAnim
道理同上。否则的话,要么动画很丑(页面突然消失,闪黑),要么下层执行的动画被挡住看不见,感觉不到动画效果。
c.参数最好不要传0
这样的话对应的动画页面会一下子消失,背景黑乎乎一片,没有丝毫美感,用一个R.anim.none代替吧,如下:
d.两个动画的执行时间最好一致,这样动画步调相同,看起来比较和谐。
5.0版本以上,Activity Transition提供了更加完美的界面切换动画,在需要跳转的场景中,通过调用startActivity(intent,options)(API16以上使用),参数Bundle options是对Activity如何启动的额外操作,该参数一般通过activityOptions.toBunble()来获取。(注意如果调用startActivity(intent)实现跳转,5.0以上设置的transition动画是不起作用的)
ActivityOptions是一个帮助获取Bundle(Activity启动额外操作)的类,内部提供了丰富的api
其中常用的三种API:
// 普通Transition启动Activity
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
// 单个共享的View
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, shareView, "shareName");
// 多个共享的View Pair是可变长参数,可通过构造函数或Pair.Create(view,shareName)来指定view和transitionName
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
Pair.create(view1, "shareName1"),
Pair.create(view2, "shareName2"));
如果不想使用transition可以设置options bundle为null。当需要结束当前Activity并回退这个动画时调用Activity.finishAfterTransition()方法。
类型
Activity的动画主要是指Enter(进入)或Exit(退出)时实现的动画效果。常见的是从右向左滑进,从左向右滑出。
如上所述可通过配置style主题或是overridePendingTransition(enterAnim,exitAnim)来实现。
5.0开始定义了另外的两种类型:
ReturnTransition & ReenterTransition
Return and Reenter Transitions are the reverse animations for Enter and Exit respectively.
这四种类型的区别:
setExitTransition() - 当A start B时,使A中的View退出场景的transition
setEnterTransition() - 当A start B时,使B中的View进入场景的transition
setReturnTransition() - 当B 返回 A时,使B中的View退出场景的transition
setReenterTransition() - 当B 返回 A时,使A中的View进入场景的transition
那么,5.0的特别的是我们可以在Activity的onCreate()中通过如下方式来指定进入或退出的动画
private void setupWindowAnimations() {
Fade fade = new Fade();
fade.setDuration(1000);
getWindow().setEnterTransition(fade); // 进入动画
Slide slide = new Slide();
slide.setDuration(1000);
getWindow().setReturnTransition(slide); // B-->A(A已启动,重返A)时触发 B调用returnTransition() 同时A调用reenterTransition()
}
或是通过TransitionInflater加载xml
Slide slide = TransitionInflater.from(this).inflateTransition(R.transition.activity_slide);
getWindow().setExitTransition(slide);
另外也可以在style.xml
中设置
Transition的实现
通过上述的介绍我们认识了如何启动5.0的Activity过渡动画,接下来就是了解Transition的各种动画效果和Target View的关联
普通的Transition的三种方式:
explode:从场景的中心移入或移出
slide:从场景的边缘移入或移出
fade:调整透明度产生渐变效果
如上述的示例代码就是通过xml或创建Slide/Fade/Explode对象指定相关参数来实现动画效果的。
Shared Elements Transition 共享元素转换
如图ActivityA
ActivityB
中都存在共同的Item,称之为共享元素,那么当A-->B时,我们就可以给目标Item设置需要的动画效果,即是ActivityA
中的Item过渡到ActivityB
中的Item。
共享元素实现的效果有:
changeBounds - 改变目标视图的布局边界
changeClipBounds - 裁剪目标视图边界
changeTransform - 改变目标视图的缩放比例和旋转角度
changeImageTransform - 改变目标图片的大小和缩放比例
实现步骤:
a) 在目录res
下创建transition
文件夹存放transition动画资源
transition/changebounds.xml
values/styles.xml
b) 在layout中声明共享元素
layout/activity_a.xml
layout/activity_b.xml
c) 使用 ActivityOptions.makeSceneTransitionAnimation()启动Activity
上述效果也可通过Java代码来实现:此处省略
Target
节点通过Id指定需要实现动画的View
如上,slide动画指定的target是cardview
,意思是cardview从bottom滑入,fade动画指定的target有状态栏、导航栏、cardview
,都是实现渐变的动画效果
Animate Reveal
CircleReveal实现圆形缩放效果,可突出显示某个部分。也是android5.0引入的效果,和共享元素一样在低版本上(5.0以下)运行会报错( 抛出.createCircularReveal() not found)。
实现方法:
调用ViewAnimationUtils下的createCircularReveal方法,方法返回一个Animator对象,这个Animator可以设置动画响应属性,调用start方法开始播放动画,CircularReveal实际上是一个属性动画,设置和属性动画是一样的。
private Animator animateRevealColorFromCoordinates(int x, int y) {
float finalRadius = (float) Math.hypot(viewRoot.getWidth(), viewRoot.getHeight());
Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, x, y, 0, finalRadius);
viewRoot.setBackgroundColor(color);
anim.setInterpolator(new AccelerateDecelerateInterpolator());
anim.start();
}
参考
实现Android5.0过渡动画兼容库
Material-Animations
Android 中的转场动画及兼容处理