Fragment嵌套Fragment
問題1、fragment嵌套fragment不顯示問題
通常時候,我們制作底部Tab切換,會用到fragment。即一個Activity下,使用4種fragment。這次遇到的問題是關于fragment再次嵌套fragmen的問題,功能需要在其中一個fragment中再次嵌套frament,使用viewPager嵌套,此時需要注意一點,使用viewpager包裹住子fragment,我們都知道viewpager需要傳入一個adapter,而此adaper需要一個fragmentManager,注意了!!!!!!這個fragmentManager必須是getChildFragmentManager。不能使用mActivity.getSupportFragmentManager()。造成的后果就是不顯示問題了,關鍵是沒有任何報錯信息,一開始著實困擾了我好一陣子。
?
關于getChildFragmentManager和getSupportFragmentManager的區別:
首先需要知道一點:getSupportFragmentManager是在v4包下的,如果不是v4包下的,則稱getFragmentManager。
我們先看getChildFragment的源碼是怎么解釋他的:
返回一個私有的管理器manager,該manager用于放置和管理子fragment。即getSupportFragmentManager獲取到的是當前fragment的下一級的fragments的管理器。
getSupportFragmentManager的源碼解釋:
getFragmentManager也是一樣的。 返回與此activity相關聯交互的manager。即返回的是activity下的管理器,用于管理activity下與之相關聯的fragent。
如果我們在父fragmen中調用getFragmentManager或者getSupportFragmentManager,返回的是activity下的manager,即把自己添加進來的manager。這就是上文提到的frag不顯示的問題所在。
額外小栗子:加入FragmentA下有一個子FragmentB,(A包含B)。fragmentB調用getFragmentManager,得到的是fragmentA下的manager,即得到的是A調用的getChildFragmentManager。
結論:getFragmentManager()是本級別管理者, getChildFragmentManager()是下一級別管理者.
?
?
問題2、子fragment嵌套在xml文件中
官網中有這么一句話;
Note: You cannot inflate a layout into a fragment when that layout includes a <fragment>. Nested fragments are only supported when added to a fragment dynamically.?簡單來說,fragment不能寫死在某個Fragment的xml文件中,fragment只能支持動態的添加進另一個fragment中。
如果Fragment被嵌套寫在了布局里, inflate到這個標簽的時候就相當于將它加進了FragmentManager里.
如果嵌套的parent fragment因為需要重建View而重新走了onCreateView()方法, 再次inflate, 此時就會拋出異常: InflateException in Binary XML
之前為什么可以呢? 非嵌套的情況, fragment直接加在activity里, 如果需要重新inflate, 必定是在onCreate()里, activity是重新建的, 所以沒有問題, 因為不存在fragmentManager中已經持有同一個fragment的問題.
舉一個例子:
在嵌套的情況下, 如果FragmentE布局里有FragmentA, 這時候我們需要疊加一個FragmentD.
用了replace(), 并且addToBackStack().
當D顯示的時候, E實際上View是被銷毀的, 然后back回來, 重建View, 即FragementE需要重新從onCreateView
()開始走生命周期, 走到inflate的時候又看到了fragmentA的標簽.
但是這時候A實際上還在FragmentManager里面, 所以就會拋出如下的異常:
android.view.InflateException: Binary XML file line # XX: Binary XML file line #XX: Error inflating class fragment
崩潰的位置就在parent fragment(FragmentE) inflate的時候.
?
問題3、把fragment放在一個動態布局里
把fragment放在一個動態布局里 -> java.lang.IllegalArgumentException: No view found for id
發現這個錯誤是因為項目中的一個子Fragment是添加在RecyclerView里面的一塊的.
RecyclerView要等到Loader的數據取到了之后再populate每一塊的布局.
還是上面的流程, 啟動父fragment, load數據, 添加子fragment, 這都沒有問題.
但是一旦如果是上面的replace()加addToBackStack() , 并且再次返回, 就會出現異常.
因為當重建View的時候, fragmentManager其中是持有child fragment的, 但是找不到它的container, 于是就會拋出異常.
栗子:
在Fragment F中, 先添加一個FrameLayout, 再把child fragment A加進去.
然后在Activity中, 用D replace F, 按back鍵返回, 就會有crash:
這是因為返回的時候FragmentManager找不到對應的container了.
所以應該避免這種做法, 盡量把fragment加進parent的根布局里, 而不是某個動態添加的布局.
補充
1.推薦使用v4包下的fragment,兼容性更強
2.除了上面提到的viewpager中添加fragment,還可以動態的添加fragment。此時需要用到的也是getChildFragmentManager。
Fragment fragment = new CharFrag();FragmentTransaction transaction = getChildFragmentManager().beginTransaction();transaction.add(R.id.charXXXX_fragment, fragment).commit();?對于其內部的子fragment,比如這里的CharFrag,可以使用getParentFragment()方法獲取到宿主fragment。
參考:https://www.cnblogs.com/mengdd/p/5552721.html
?
總結
以上是生活随笔為你收集整理的Fragment嵌套Fragment的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用navicat新建sqlite数据库
- 下一篇: 用 TableModel Free 框架