場景:
- A打開B頁面,A頁面保持不動,B頁面從底部滑入顯示
- B返回A頁面,A頁面保持不動, B頁面從頂部向下滑出消失
1:通過Theme的windowAnimationStyle屬性實現
<style name="Kt.DownIn" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowAnimationStyle">@style/AudioPlayAnim</item>
</style>
<style name="AudioPlayAnim" parent="@android:style/Animation.Activity">
<!--馬上要進入到的Activity的動畫,頁面B-->
<item name="android:activityOpenEnterAnimation">@anim/anim_bottom_in</item>
<!--馬上要推到后臺或者finish的Activity的動畫,頁面A-->
<item name="android:activityOpenExitAnimation">@anim/anim_no</item>
<!--退出即將回到的Activity的動畫,頁面A-->
<item name="android:activityCloseEnterAnimation">@anim/anim_no</item>
<!--當前即將finish退出的Activity的動畫,頁面B-->
<item name="android:activityCloseExitAnimation">@anim/anim_bottom_out</item>
</style>
使用過程用,如果沒有設置android:activityOpenExitAnimation和android:activityCloseEnterAnimation這兩個A頁面的消失動畫,就可能會出現短暫的黑屏交互現象;
如果theme設置windowIsTranslucent為true,則建議繼承Animation.Translucen,否則動畫可能不生效,如下:
<style name="AudioPlayAnim" parent="@android:style/Animation.Translucen">
<item name="android:windowEnterAnimation">@anim/anim_bottom_in</item>
<item name="android:windowExitAnimation">@anim/anim_bottom_out</item>
<!--馬上要進入到的Activity的動畫,頁面B-->
<item name="android:activityOpenEnterAnimation">@anim/anim_bottom_in</item>
<!--馬上要推到后臺或者finish的Activity的動畫,頁面A-->
<item name="android:activityOpenExitAnimation">@anim/anim_no</item>
<!--退出即將回到的Activity的動畫,頁面A-->
<item name="android:activityCloseEnterAnimation">@anim/anim_no</item>
<!--當前即將finish退出的Activity的動畫,頁面B-->
<item name="android:activityCloseExitAnimation">@anim/anim_bottom_out</item>
</style>
另外一種解決windowIsTranslucent為true的時候,動畫效果不生效的方案:
open var activityCloseEnterAnimation: Int = 0
open var activityCloseExitAnimation: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initWindowAnimAttr()
}
@SuppressLint("ResourceType")
private fun initWindowAnimAttr() {
try {
var activityStyle = theme.obtainStyledAttributes(intArrayOf(R.attr.windowAnimationStyle))
val windowAnimationStyleResId = activityStyle.getResourceId(0, 0)
activityStyle.recycle()
activityStyle = theme.obtainStyledAttributes(windowAnimationStyleResId, intArrayOf(R.attr.activityCloseEnterAnimation, R.attr.activityCloseExitAnimation))
activityCloseEnterAnimation = activityStyle.getResourceId(0, 0)
activityCloseExitAnimation = activityStyle.getResourceId(1, 0)
activityStyle.recycle()
} catch (e: Exception) {
}
}
override fun finish() {
super.finish()
isDestroy = true
overridePendingTransition(activityCloseEnterAnimation, activityCloseExitAnimation)
}
anim_bottom_in, anim_no以及anim_bottom_out的動畫文件如下
!---anim_bottom_in
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="100%"
android:interpolator="@android:anim/decelerate_interpolator"
android:toYDelta="0" />
</set>
!---anim_no
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"http://一定要設置跟進入動畫相同的時間,解決黑屏的關鍵
android:fromYDelta="0"
android:interpolator="@android:anim/decelerate_interpolator"
android:toYDelta="0" />
</set>
!---anim_bottom_out
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="0"
android:interpolator="@android:anim/decelerate_interpolator"
android:toYDelta="100%" />
</set>
2: 通過overridePendingTransition實現效果
在頁面B的onCreate方法和finish方法中加入以下代碼
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
overridePendingTransition(R.anim.anim_bottom_in,R.anim.anim_no)
}
//重寫finish方法
override fun finish() {
super.finish()
overridePendingTransition(R.anim.anim_no,R.anim.anim_bottom_out)
}
同樣anim_no頁面的消失動畫一定要設置