它包括两个部分:一部分是第一个activity退出时的动画;另外一部分时第二个activity进入时的动画;
在Android的2.0版本之后,有了一个函数来帮我们实现这个动画。这个函数就是overridePendingTransition
这个函数有两个参数,一个参数是第一个activity退出时的动画,另外一个参数则是第二个activity进入时的动画。
这里需要特别说明的是,关于overridePendingTransition这个函数,有两点需要主意
1.它必需紧挨着startActivity()或者finish()函数之后调用"
2.它只在android2.0以及以上版本上适用
overridePendingTransition(R.anim.alpha_rotate, R.anim.my_alpha_action);
如果要定义统一的风格的进入动画,并且还要有退出的动画,在每个activity里实现overridePendingTransition是很麻烦的
我们可以定义一个style主题的形式
一个 anim_enter.xml
<?xml version="1.0" encoding="UTF-8"?>
<set android:interpolator="@android:anim/decelerate_interpolator"
xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:duration="@android:integer/config_mediumAnimTime" android:pivotX="69.99999%" android:pivotY="100.0%" android:fromXScale="0.0" android:toXScale="1.0" android:fromYScale="0.0" android:toYScale="1.0" />
<alpha android:duration="@android:integer/config_mediumAnimTime" android:fromAlpha="0.0" android:toAlpha="1.0" />
</set>
anim_exit.xml
<?xml version="1.0" encoding="UTF-8"?>
<set android:interpolator="@android:anim/accelerate_interpolator"
xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:duration="@android:integer/config_mediumAnimTime" android:pivotX="69.99999%" android:pivotY="100.0%" android:fromXScale="1.0" android:toXScale="0.0" android:fromYScale="1.0" android:toYScale="0.0" />
<alpha android:duration="@android:integer/config_mediumAnimTime" android:fromAlpha="1.0" android:toAlpha="0.0" />
</set>
上面的两个xml分别对应overridePendingTransition(int enterAnim, int exitAnim) 中的进入和退出动画
定义当另一个activity退出时的动画效果,back_enter.xml
<?xml version="1.0" encoding="UTF-8"?>
<set android:interpolator="@android:anim/decelerate_interpolator"
xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:duration="@android:integer/config_mediumAnimTime" android:pivotX="50.0%" android:pivotY="50.0%" android:fromXScale="1.5" android:toXScale="1.0" android:fromYScale="1.5" android:toYScale="1.0" />
<alpha android:duration="@android:integer/config_mediumAnimTime" android:fromAlpha="0.4" android:toAlpha="1.0" />
</set>
back_exit.xml
<?xml version="1.0" encoding="UTF-8"?>
<set android:interpolator="@android:anim/decelerate_interpolator"
xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:duration="@android:integer/config_mediumAnimTime" android:pivotX="50.0%" android:pivotY="50.0%" android:fromXScale="1.0" android:toXScale="0.4" android:fromYScale="1.0" android:toYScale="0.4" />
<alpha android:duration="@android:integer/config_mediumAnimTime" android:fromAlpha="1.0" android:toAlpha="0.0" />
</set>
应该定义一个样式,在所有包裹activity的地方引入样式。这样我们就想到了AndroidManifest.xml里的application 了
声明theme
<style name="ThemeActivity" mce_bogus="1">
<item name="android:windowAnimationStyle">@style/AnimationActivity</item>
<item name="android:windowNoTitle">true</item>
/style>
style
<style name="AnimationActivity" parent="@android:style/Animation.Activity" mce_bogus="1">
<item name="android:activityOpenEnterAnimation">@anim/anim_enter</item>
<item name="android:activityOpenExitAnimation">@anim/anim_exit</item>
<item name="android:activityCloseEnterAnimation">@anim/back_enter</item>
<item name="android:activityCloseExitAnimation">@anim/back_exit</item>
以上的两两配套,如果定义一个会显得很难看,
android:activityCloseEnterAnimation
指的是关闭activity b,activity a 出来时的动画,
android:activityCloseExitAnimation
指activity b关闭的动画,作用与finish操作
如果你不想使用style和theme方式定义,那可以使用overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right) ;这个方法
在startActivity后边使用,代表的是android:activityOpenEnterAnimation ,android:activityOpenExitAnimation
在finish后使用代表的是android:activityCloseEnterAnimation
android:activityCloseExitAnimation
在AndroidManifest.xml里边声明
<application
android:icon="@drawable/ic_launcher" android:theme="@style/ThemeActivity"</span>
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".GlobalAnimationActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".OtherActivity"></activity>
</application>
再来看看overridePendingTransition页面跳转动画的原理
看activity源码可知
代码
ActivityManagerNative.getDefault().overridePendingTransition(mToken, getPackageName(), enterAnim, exitAnim);
ActivityManagerNative是什么呢?
看其定义:public abstract class ActivityManagerNative extends Binder implements IActivityManager
需要用到android系统的IPC知识
android本身有很多Service,这些服务从开机启动就一直在跑,比如media,比如windowmanager,这些服务对外提供接口,有些是一直到最上层都要用到的,比如Media,有些只给内部用,比如windowmanager(这个是service,别跟我们用的WindowManager混淆了)
只给内部用和给上层用是两种不同的概念。因为内部用的话他们是同一个进程,没必要跨进程通信,也就是没ipc问题,而给外部用,就需要Ipc了
ActivityManagerNative,他就是IActivityManager的【本地】代理,ActivityManagerNative.getDefault()得到的就是IActivityManager对象。IActivityManager又是毛???没错,它是WindowManagerService的顾客。。。它里面就是跟WindowManagerService通信
,IActivityManager里面的overridePendingTransition直接跟server端通话。
“Hello,啊 ,WindowManagerService,我是你的代理IActivityManager君啊,刚接到任务要改变activity的切换画面啊。"
"ok,IActivityManager,在外面风吹日晒的辛苦你了,其他的交给我吧。作为NB哄哄的Service大人,我帮你解决之。“
毫不犹豫的,WindowManagerService执行以下代码:
public void overridePendingAppTransition(String packageName,
int enterAnim, int exitAnim) {
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mNextAppTransitionPackage = packageName;
mNextAppTransitionEnter = enterAnim;
mNextAppTransitionExit = exitAnim;
}
}
,这下已经到了WindowManagerService了,这个方法(overridePendingAppTransition)中mNextAppTransitionEnter等变量赋值。
这些变量在window进行切换的时候会进行处理。remove->removeWindow->removeWindowLocked->applyAnimationLocked(注意,这些说的都是WindowManagerService中的方法)
那么这个remove(具体是
public void remove(IWindow window) {
removeWindow(this, window);
})什么时候用的呢,这个,这个。。。。在ViewRoot和SurfaceView中都会调用到的