Bootstrap

Fragment相关常用方法解析

add()方法相关

add(R.id.layout,fragment,tag)方法实际是往传入的layout上加一层视图,你可以尝试添加多个Fragment在同一个layout上,但会出现重叠现象。add()方法调用Fragment的生命周期为:在这里插入图片描述

remove()

remove(fragment)是销毁该fragment实例,其生命周期调用为:
在这里插入图片描述

replace()方法相关

replace(R.id.layout,fragment,tag)方法会替换掉旧的Fragment(它会将所有在这个layout上显示的Fragment销毁掉),创建新传入的Fragment并显示在视图上。新传入的Fragment,会执行同add()方法所调用的生命周期,而旧的Fragment会依次调用在这里插入图片描述
但上述旧的Fragment所执行的生命周期有个大前提,就是未将事务提交到回退栈(下文会提到另一种情况)。

hide()方法和show()方法

hide()和show()最终是让Fragment的view执行view.setVisibility,并不会调用Fragment的生命周期,但使用hide()方法时,被隐藏的Fragment会调用onHiddenChanged(hidden: Boolean)

addToBackStack()popBackStack()相关

addToBackStack()方法是让本次事务操作放进回退栈(之前一直以为是将Fragment放进回退栈)。

验证:

val transition1:FragmentTransaction=manager.beginTransaction()
        transition1.add(R.id.tv_fa,fFragment,"first")
            .addToBackStack("aa") //tag是用来标记本次事务操作的
            .commit()

        val transaction2=manager.beginTransaction()
        transaction2.add(R.id.tv_fa,sFragment,"second")
            .add(R.id.tv_fa,tFragment,"thrid")
            .addToBackStack("bb")
            .commit()

上述代码中我们add了三个fragment所以三个会重叠在一起。像这个样子
不太好看的亚子。
此时我们点击Back键会是这个样子
在这里插入图片描述
生命周期的调用是这个样子。
在这里插入图片描述
没错点击Back键使我们最后一次提交的事务操作出栈,所以thridFragment和secondFragment都被清理出栈。

popBackStack()

如果我们在上面代码中加上
bt.setOnClickListener { supportFragmentManager.popBackStack("aa",FragmentManager.POP_BACK_STACK_INCLUSIVE) }

我们点击Button,会是这个样子
在这里插入图片描述
popBackStack(tag,flag)作用和点击Back键差不多,都是让事务操作记录出栈。这里的第一个参数是我们将事务添加到回退栈所设的tag。第二个参数FragmentManager.POP_BACK_STACK_INCLUSIVE表示让回退栈中该事务(包含该事务)之上的所有事务都出栈;flag还可取0,表示表示让回退栈中该事务(不包含该事务)之上的所有事务都出栈。
代码中“aa“是我第一次提交的事务操作,FragmentManager.POP_BACK_STACK_INCLUSIVE)让该事务及它之上的所有事务出栈。所以点击button后,layout上就没有任何fragment显示。
另外popBackStack()底层是通过Handler执行的,所以不是立即执行的,popBackStackImmediate()则会立即执行。

当我们将事务操作添加到回退栈后,在用replace时会发生什么

        val transition1:FragmentTransaction=manager.beginTransaction()
        transition1.add(R.id.tv_fa,fFragment,"first")
            .addToBackStack("aa")
            .commit()
            
        val bt=findViewById<Button>(R.id.bt_main)
        
        bt.setOnClickListener {
            val faFragemnt=MyFragment("fourth")
            val transaction=manager.beginTransaction()
            transaction.replace(R.id.tv_fa,faFragemnt,"fourth")
                .commit()
  
        }

我们点击Button后有
在这里插入图片描述
可以看到firstFragment生命周期的调用,它只是被DestoryView,并没有被完全销毁,这和直接使用replace不一样。即加入回退栈的Fragment不会被replace方法销毁,只是DestoryView,我们可以通过findFragmentByTag()orfindFragmentById()找到该Fragment。当事务操作加入了回退栈,使用remove也是类似的情况,不会删除对应的fragment实例,只是destoryView。

;