日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Fragment嵌套Fragment

發布時間:2023/12/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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:

java.lang.IllegalArgumentException: No view found for id 0x7f0c0062 (com.example.ddmeng.helloactivityandfragment:id/frame_container) for fragment FragmentA{b37763 #0 id=0x7f0c0062 FragmentA}at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:965)at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1130)at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1953)at android.app.Fragment.performActivityCreated(Fragment.java:2234)at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:992)at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)at android.app.BackStackRecord.popFromBackStack(BackStackRecord.java:1670)at android.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1587)at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:578)at android.app.Activity.onBackPressed(Activity.java:2503)

這是因為返回的時候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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。