Transition动画效果诞生于Android 4.4,主要负责:
- 捕捉在开始场景和结束场景中每个 View 的状态。
- 根据视图一个场景移动到另一个场景的差异创建一个 Animator。
应用场景包括:
- 可以在activity之间跳转的时候添加动画
- 动画共享元素之间的转换活动
- activity中布局元素的过渡动画
我们以前实现Activity切换过程的动画的姿势是这样的:
- xml设置
首先我们需要在AndroidManifest.xml
清单文件中application
节点使用的theme主题添加属性:<item name="android:windowAnimationStyle">@style/AnimationActivity</item>
AnimationActivity的属性如下:
<!--Activity进入、退出动画-->
<style name="AnimationActivity" parent="@android:style/Animation.Activity">
<item name="android:activityOpenEnterAnimation">@anim/in_from_right</item>
<item name="android:activityOpenExitAnimation">@anim/in_from_right_abit</item>
<item name="android:activityCloseEnterAnimation">@anim/out_to_right_abit</item>
<item name="android:activityCloseExitAnimation">@anim/out_to_right</item>
</style>
然后在res/anim
中创建对应的文件即可。
- 代码设置
通过在Activity中重写overridePendingTransition
给当前界面添加进入、退出动画,具体自行搜索,因为这篇博客的重点是在 Transition Animation 上。
进入主题 首先有三种自带的Transition Animation效果
- fade
- slide
- explode
其次生成的方式有2种:
- xml生成
在res
下创建transition
资源文件夹,在该文件夹中创建xml文件,比如:slide.xml
:
<?xml version="1.0" encoding="utf-8"?>
<slide xmlns:android="http://schemas.android.com/apk/res/"
android:duration="500"/>
- 代码生成
android.transition.Slide slide = new android.transition.Slide();
//动画时长
slide.setDuration(500);
//动画从哪个方向执行
slide.setSlideEdge(Gravity.TOP);
//动画的状态:MODE_OUT:退出、MODE_IN:进入
slide.setMode(Visibility.MODE_OUT);
使用Transition Animation的姿势如下:
- 在
AndroidManifest.xml
清单文件中application
节点使用的theme主题添加属性(这种方法是在整个app中使用):
<!--转场动画-->
<!--启用窗口内容转换-->
<item name="android:windowContentTransitions">true</item>
<!-- 启用Transition框架,但没有默认的动画, 需要通过bundle设定动画,设定false则从ContentTransition中关闭此效果-->
<item name="android:windowActivityTransitions">true</item>
<!--是否允许动画重叠-->
<item name="android:windowAllowEnterTransitionOverlap">false</item>
<item name="android:windowAllowReturnTransitionOverlap">false</item>
在指定的Activity中使用:
在Activity重写的onCreate方法中,在super.onCreate(savedInstanceState);之前添加如下代码:
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setAllowReturnTransitionOverlap(false);
- 在需要动画效果的
Activity
中添加如下代码:slide.xml引入方式
:
Transition slide = TransitionInflater.from(this).inflateTransition(R.transition.slide);
getWindow().setEnterTransition(slide);
代码生成方式
:
android.transition.Slide slide = new android.transition.Slide();
//动画时长
slide.setDuration(500);
//动画从哪个方向执行
slide.setSlideEdge(Gravity.TOP);
//动画的状态:MODE_OUT:退出、MODE_IN:进入
slide.setMode(Visibility.MODE_OUT);
getWindow().setEnterTransition(slide);
- 在调起这个
Activity
的Activity
中使用如下方式(注意这一步很重要):
// 一定要用这种方式startActivity
startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(activity). toBundle());
然后你就可以看到效果了。
然而事情还没有这么简单,这里只是进入的效果,假如我们指定要从A进入B时,A的退场动画、B的进场动画,B finishi 返回A时,B的返回动画、A的重入动画,那该采用怎样的姿势?
那么我们首先弄清楚四个方法:
• setExitTransition():当 A 启动 B 时, A 离开场景的退出过渡动画,在A中设置
• setEnterTransition():当 A 启动 B 时, B 进入场景的进入过渡动画,在B中设置
• setReturnTransition():当 B 返回 A 时, B 离开场景的返回过渡动画,在B中设置
• setReenterTransition():当 B 返回 A 时, A 进入场景的重入过渡动画,在A中设置
其中,如果 setReturnTransition
和 setReenterTransition
方法没有指定,那么会将 setExitTransition
和 setEnterTransition
指定的动画反过来执行。
还有要注意的一点是:如果要使B返回A时,A的重入过渡动画(即 setReenterTransition()
方法所设置的动画)和B的返回过渡动画(即 setReturnTransition()
方法所设置的动画)生效,必须在B中使用 finishAfterTransition()
方法退出。
了解了这几种方法的区别之后,我们就好摆姿势了(以下均使用代码创建方式):
- 在A Activity 中添加如下代码:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
super.onCreate(savedInstanceState);
setContentView(R.layout.a);
setupWindowAnimations();
findViewById(R.id.toB).setOnClickListener(view -> {
Intent intent = new Intent(A.this,B.class);
// 一定要采用这种方式启动B Activity
startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(A.this). toBundle());
});
}
private void setupWindowAnimations() {
android.transition.Explode explode= new android.transition.Explode();
explode.setDuration(500);
getWindow().setExitTransition(explode); // A 离开场景的退出过渡动画
getWindow().setReenterTransition(explode); // A 进入场景的重入过渡动画
//不允许动画重叠
getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setAllowReturnTransitionOverlap(false);
}
- 在B Activity 中添加如下代码:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
super.onCreate(savedInstanceState);
setContentView(R.layout.b);
setupWindowAnimations();
}
private void setupWindowAnimations() {
android.transition.Explode explode= new android.transition.Explode();
explode.setDuration(500);
getWindow().setEnterTransition(explode); // B 进入场景的进入过渡动画
getWindow().setReturnTransition(explode); // B 离开场景的返回过渡动画
//不允许动画重叠
getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setAllowReturnTransitionOverlap(false);
}
...
// 退出时调用该方法
finishAfterTransition();
至此,动画效果就可以展现了。