Android FragmentManager使用
1.获取fragmentManager
要想使用好fragmentmanager,第一步肯定先要正确获取他呀:
- 获取activity中的fragmentmanager:在activity中
getFragmentManager()
或getSupportFragmentManager()
(这个用于support包的fragment,向下兼容,现api28后变成support包全部转为Androidx)如果在fragment中则可以先getactivity()
获取到其依赖的activity - 获取在fragment中的fragmentmanager:
getChildFragmentManager()
这种情况用于fragment中嵌套fragment,同时子fragment可以通过getParentFragment()
获得
2.事务
- 在Android中fragmentManager是以事务为单位来管理的,每次我们都通过
fragmentManager.beginTransaction()
来获得一个FragmentTransaction对象,然后进行添加,替换,删除等,最后commit提交,这整个过程从begin到commit进行的所有操作就是一个事务,每个commit提交一个事务 - 这里要注意commit调用commit()方法并不立即执行这个事务,而是在Activity的UI线程之上(”main”线程)调度运行,以便这个线程能够尽快执行这个事务,这意味这个commit是异步的,所以必要时可以通过
commitNow()
来立即执行
2.fragmentManager的各种方法
add()
add方法会直接将一个fragment添加到指定的id布局中,不管这个布局容器中原来有没有,无条件覆盖。所以会叠加,而之前的fragment只是被遮挡,view并不会被摧毁getFragmentbyTag()
与getFragmentbyId()
这两个方法可以获得有相应的tag或id属性的fragment(这两个属性也可以通过xml里布局设置),那么就出现了有多个fragment拥有相同的tag和id,那调用该方法获得的是哪个呢?实测获得的是最顶层的那个fragment,也就是最近添加的replace()
该方法不同于add()可有其注释的出,relplace()会先相应调用该布局id容器中中所有的add的fragment的remove()
方法,然后在调用add()
方法remove()
移除这个fragment,最后会调用onDetach()
show()
和hide()
,这里要注意调用这两个方法并不会走fragment的生命周期,which means 并不会调用onPause()
,onStop
方法,而是只调用了onHiddenChanged()
方法,所有改变应在这个方法里,重写之addToBackTrack()
最后说一下fragment的回退栈,注意,只有在commit事务是调用了addToBackTrack()
方法,才会有回退栈,才会在回退栈里添加,否则就没有回退栈,pop方法不会有任何改变。addToBackTrack()
即把本次事务的所有操作储存起来,注意调用了addtobaktrack后remove方法不会真的把fragment移除,而只是distroy了它的view,并没有调用onDetach()
,也就是说它还连接在宿主中。popbackTrack
,该方法即将回退栈中的最近的一次事务pop出来,也就是反过来调用方法,add就是remove,remove就add,所以如果这个调用了replace,那么pop后就会将这个replace add的fragment移除,然后在把之前remove的所有fragment add到里面。而之前就存在的fragment依然存在,没有变化,就像是add覆盖到上面一样。所以加入回退栈后pop可以回到上次操作