今天开发app的时候,又碰到了一个我疑惑了很久的问题:fragment碎片动态切换怎么切换,正常的replace , addBackStack 这几个会出现一些bug ,比如说,你如果没有将 主页的fragment添加到栈中, 那你点到另一个fragment后会丢失当前你在主页的一些数据,比如输入框内容

8Y37_`X8JRO`(38B`3DDVQ0.jpg
要想解决这个问题,就得使用 addToBackStack()方法,添加到栈中去,不过这样做了当你重复点击首页的话会重复创建界面,并且,当你点击返回键,会返回到上一个fragment,很让人头疼,所以我花了个流程图,解决了这几个问题,概括了一下,具体还是看我的代码

9B$WE6G@T%%997B7$%K_3WJ.jpg
用文字表述一下:
首先,定义两个变量 , 添加的fragment , 此时顶层的 targetFragment
然后,定义一个changeFragment()方法 ,传入参数为:fragment
接下来方法中第一步: 判断target是否初始化,若没有初始化,说明是第一次给界面添加碎片执行代码
fun changeFragment(fragment : Fragment){
val ft = supportFragmentManager.begainTransaction()
if(this::targetFragment . isInitialize){
ft.add( "这里填你的fragmetn容器的 id ", fragment )
.addToBackStack("")
.commit()
//然后将 target赋值 ,表示顶层的fragmetn就是这个
targetFragment = fragment
}
}
``
###上面就是第一次定义的代码
那么如果此时容器中已经有 fragment了, 那么该怎么去显示??
//判断是否存在于栈中,是否已经被添加
if(fragment.isAdded){
if(fragment != targetFragment ){
ft.hide(targetFragment)
.show(fragment)
.commit()
}
}else{
//如果没有被添加,那么就
ft.add("fragment容器的id" , fragment)
.hide(targetFragment)
.commit()
}
//最后一步,别忘了给 targetFragment赋值
targetFragment = fragment
在activity中,如果你像我一样添加了这些fragment, 并且添加到了栈中,返回一下会导致返回上一个加载的fragment
所以重写一个方法-----onBackPress(){
//只需要将super.onBackPress()去掉就可以了
//并且添加上一行
finish() //可以改根据自己需要去操作,比如点击两下退出程序...
}
因为比较忙,所以这篇写的有点仓促,希望能帮助到被fragment动态切换困惑的你,谢谢观看、最后贴上方法,
fun changeFragment(fragment : Fragment){
val bt = supportFragmentManager.beginTransaction()
if( ! this::targetFragment.isInitialized ){
//如果target还没有初始化,那么说明是第一次添加
bt.add(R.id.fragment_container_main , fragment).commit()
targetFragment = fragment //并且将添加的设置为顶层的fragment
return
}
//如果这个fragment已经
if(fragment.isAdded){
if(fragment != targetFragment){
bt.hide(targetFragment).show(fragment).commit()
}
}else{
bt.add(R.id.fragment_container_main , fragment)
.addToBackStack("main")
.hide(targetFragment)
.commit()
}
//最后一步就是将target指定为
targetFragment = fragment
}
override fun onBackPressed() {
//将super.()去掉就可以禁止返回了
ToastUtil.show("禁止返回了!")
//但是可以退出!
}
``