先說一下出現崩潰的問題:頁面是一個有很多下一步的界面,不想點擊下一步就打開一個新的Activity,所以就點擊下一步時切換Fragment,並使用回退棧處理返回事件;
單Activity多Fragment有回退棧,使用replace的方式切換Fragment,非常簡單的就完成了;在初步體驗一下時發現Fragment切換有點生硬,於是我給Fragment加了切換動畫;在使用回退棧返回時問題就來了;The specified child already has a parent. You must call removeView;
我非常的費解,爲什麼我加了動畫之後回退就崩潰了呢,我去掉Fragment回退棧,這個崩潰就不復現了? 找了篇文章大概說“Fragment在動畫執行結束之後纔會把原來的實例銷燬,這個時候就會存在兩個Fragment實例在同一個頁面中(一個是回退棧中的、一個是即將顯示的)”https://www.jianshu.com/p/2146ace8a244;思索後發現時replace切換Fragment的問題,使用add\show\hide就不會出現這個問題;
簡單說一下Fragment切換動畫和回退棧:
Fragment切換動畫:
默認漸隱漸顯動畫:
supportFragmentManager.beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
自定義動畫效果:
setCustomAnimations有四個參數:
參數一:fragment添加到頁面上時的進場動畫;
參數二:fragment從頁面上移除時的出場動畫;
參數三:使用回退棧時,該fragment添加到頁面上時的進場動畫;(從Fragment棧中重新顯示到頁面上時)
參數四:使用回退棧時,該fragment從頁面上移除時的出場動畫;(從Fragment棧中移除時)
supportFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.slide_right_in,R.anim.slide_right_out,R.anim.slide_lift_in,R.anim.slide_lift_out)
隨便貼出來一個動畫效果:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="100%p"
android:toXDelta="0%p"
android:duration="300"/>
<alpha
android:fromAlpha="0.5"
android:toAlpha="1.0"
android:duration="300"/>
</set>
Fragment回退棧:
supportFragmentManager.beginTransaction().addToBackStack(backStackName)
backStackName就是該Fragment在棧中的名字,可以爲null;
添加過回退棧後,點擊返回就可以做逐層出棧的操作,像Activity一樣逐層返回;如果棧中沒有Fragment則關閉該Activity;
if (supportFragmentManager.backStackEntryCount > 0){
supportFragmentManager.popBackStack()
}else{
finish()
}
Fragment的棧由activity管理,activity的棧由系統管理;