Transition Animation系列文章:
- Android动画——Activity转场动画|过渡动画一点薄见(一)((Transition Animation 系列))
- android动画——过渡动画中ActivityOptions介绍与使用((Transition Animation 系列))
1. 转场动画概述
在Android开发过程中,经常会遇到Activity之间切换的问题,转场动画就是用于布局(界面)变化时的过渡动画,即不同UI状态转换时的动画。
Transition过渡动画(转场动画)是在android4.4.2中引入的,那时只能对整个Activity或Fragment做动画,Google在Android5.0的Material Design中引入更为完整的Transition框架。
Android的过渡动画可分为四个部分:
- Activity/Fragment切换时内容过渡动画
- Activity/Fragment切换时共享元素过渡动画
- 同一个页面中的场景过渡动画
- 共享元素过渡动画 + 揭露效果
在具体学习使用过渡动画前,先花点时间捋一下当中的两个重要概念:场景(scenes)
和转换(transitions)
;场景定义了一个确定的UI状态,而转换定义了两个场景切换的动画。
当两个场景切换时,Transition主要有以下两个行为:
- 确定开始场景和结束场景中每个view的状态
- 根据状态差异创建Animator,用以场景切换时View的动画
下面来根据过渡动画的四个部分分别介绍,这里以Activity为例,Fragment类似。
2. Activity/Fragment切换时内容过渡动画
关于Activity/Fragment切换,这里可以细分为四个动画,例如有两个Activity,分别是A和B:
- A启动B:A发生了exit动画,B发生了enter动画
- B返回A:A发生了reenter动画,B发生了return动画
在Android 5.0(API)中默认提供了三种转换:
分解(Explode)
:从场景中心移入或移出视图滑动(Slide)
:从场景边缘移入或移移出视图淡入淡出(Fade)
:通过调整透明度在场景中增添或移除视图
2.1 Android 5.0之前
在Android 5.0之前,一般是用overridePendingTransition()
这个方法来实现内容过渡:
* @param enterAnim A resource ID of the animation resource to use for
* the incoming activity. Use 0 for no animation.
* @param exitAnim A resource ID of the animation resource to use for
* the outgoing activity. Use 0 for no animation.
*/
public void overridePendingTransition(int enterAnim, int exitAnim) {
try {
ActivityManager.getService().overridePendingTransition(
mToken, getPackageName(), enterAnim, exitAnim);
} catch (RemoteException e) {
}
}
其中
enterAnim
是进入动画,exitAnim
是退出动画
关于该方法的使用十分简单,先在XML中定义好两个Activity的切换动画,然后:
startActivity(intent);
overridePendingTransition(R.anim.bottom_top_anim, R.anim.alpha_hide);
---
finish();
overridePendingTransition(R.anim.alpha_show, R.anim.top_bottom_anim);
备注:
overridePendingTransition
方法必须在startActivity()
或者finish()
方法后面- 如果参数是0,则表示没有动画
2.2 Android 5.0 之后
在Android 5.0 之后,要启用内容过渡动画需要完成下面几个步骤:
- 打开内容转换开关
在style中设置
<style name="BaseAppTheme" parent="Theme.AppCompat.Light">
<!-- enable window content transitions -->
<item name="android:windowContentTransitions">true</item>
</style>
或者在代码中设置
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS)
}
- 指定进入、退出转换
(1)可以在style中指定转换:示例
<style name="BaseAppTheme" parent="Theme.AppCompat.Light">
<!-- specify enter and exit transitions -->
<item name="android:windowEnterTransition">@transition/activity_fade</item>
<item name="android:windowExitTransition">@transition/activity_slide</item>
</style>
转换文件存放在res/transiton
目录下
res/transition/activity_fade.xml
<?xml version="1.0" encoding="utf-8"?>
<fade xmlns:android="http://schemas.android.com/apk/res/"
android:duration="1000"/>
res/transition/activity_slide.xml
<?xml version="1.0" encoding="utf-8"?>
<slide xmlns:android="http://schemas.android.com/apk/res/"
android:duration="1000"/>
(2)除了在style中指定转换,也可以在代码中指定转换
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
setContentView(R.layout.activity_main);
setupWindowAnimations();
TextView textView = (TextView) findViewById(R.id.start_activity);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle());
}
});
}
private void setupWindowAnimations() {
// inflate from xml
Slide slide = (Slide) TransitionInflater.from(this).inflateTransition(R.transition.activity_slide);
// or create directly
// Slide slide = new Slide();
// slide.setDuration(1000);
// slide.setSlideEdge(Gravity.LEFT);
getWindow().setExitTransition(slide)