先说一下出现崩溃的问题:页面是一个有很多下一步的界面,不想点击下一步就打开一个新的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的栈由系统管理;