getSupportFragmentManager()和getChildFragmentManager()有什么区别?


77

我的课继承了Fragment,这就是为什么它不能使用getSupportFragmentManager()的原因。我正在使用getChildFragmentManager,它向我显示错误-IllegalArguementException:未找到ID的视图...错误。

任何指导将不胜感激。

调用AttachmentsListFragment的代码是

Bundle b = new Bundle();
b.putSerializable("AttachmentsList", msg.attachments);  
        AttachmentListFragment listfrag = new AttachmentListFragment(msg.attachments);
FragmentTransaction transaction = getFragmentManager().beginTransaction();       
transaction.add(R.id.attachmentslistcontainer, listfrag);
transaction.addToBackStack(null);
transaction.commit();

attachmentslayout.xml是

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/attachmentslistcontainer"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textViewAttachmentHeader"
        style="@style/Normal.Header.Toolbar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/list_separator_background"
        android:ellipsize="end"
        android:gravity="center"
        android:maxLines="2"
        android:text="@string/attachments_header"
        android:textColor="#FFFFFFFF"
        android:textSize="22sp"
        android:textStyle="bold"
        android:visibility="visible" />

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>

</FrameLayout>

AttachmentsListFragment.java

public class AttachmentListFragment extends ListFragment implements IAttachmentsData {

    ArrayList<Attachments> items = null;
    Integer cellLayoutID;
    Integer index;

    public AttachmentListFragment() {

    }

    public AttachmentListFragment(ArrayList<Attachments> items) {
        this.items = items;
        Log.i("Logging", "Items size" + items.size()); //$NON-NLS-1$
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle bundle;
        if (savedInstanceState != null) {
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        //super.onCreateView(inflater, container, savedInstanceState);

        //  setContentView(R.layout.attachmentslayout);
        View view = inflater.inflate(R.layout.attachmentslayout, container, false);
        return view;
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setListAdapter(new AttachmentAdapter(
                getActivity().getApplicationContext(),
                R.layout.attachmentslistcellcontent,
                items));
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);
        index = position;
        Intent intent = new Intent();
        Bundle b = new Bundle();
        b.putByteArray("Data", items.get(position).getImageData());
        intent.putExtras(b);
    }


    public byte[] getData() {
        // TODO Auto-generated method stub
        if (items != null && index < items.size()) {

            return items.get(index).getImageData();
        }
            return null;
    }

}

2
请在调用“ getChildFragmentManager”的地方张贴整个方法和/或类。
2013年

Answers:


152

的定义getChildFragmentManager()是:

返回一个私有的FragmentManager,用于在Fragment中放置和管理Fragment。

同时getFragmentManager()(或在本例中getSupportFragmentManager())的定义为:

返回用于与与此片段的活动关联的片段进行交互的FragmentManager。

基本上,区别在于Fragment现在拥有自己的内部组件FragmentManager,可以处理Fragments。子FragmentManager是仅处理添加到其中的Fragment中包含的Fragment的子控件。另一个FragmentManager包含在整个内Activity

在这种情况下,我猜测是您已将Fragments添加到Activity的FragmentManager。您将获得不包含您要查找的子项FragmentManager。因此,您会得到一个异常,因为它在另一个FragmentManager中找不到具有给定ID的Fragment。


3
我尝试使用getChildFragmentManager。但这也显示了相同的例外
NinjaCoder

1
我以为您说您已经在使用getChildFragmentManager。
DeeV

如果我使用getSupportFragmentManager创建一个子片段,以便父级持有该子级,并且两者都可见/在前景中,那么后退按钮有什么作用?它会弹出父母吗?还是孩子?等等。?

1
@Rai getSupportFragmentManagergetFragmentManager都是顶层的片段管理器Activity。从技术上讲,您添加的片段不是此处描述的“子片段”。它们是活动处理的片段。您在活动所处理的任一管理器的后堆栈上发布的任何片段将在“后退”弹出。
DeeV

24

getFragmentManager属于Activity
getChildFragmentManager属于Fragment

例如,我们有一个应用程序,它具有MainActivityFragment1Fragment2container_view_on_main是在布局activty_main.xml

要显示 Fragment1MainActivity我们必须使用getSupportFragmentManager()

getSupportFragmentManager().beginTransaction().replace(R.id.container_view_on_main, Fragment1.newInstance());

要显示 Fragment2Fragment1我们有2种方式

使用 getFragmentManager()

getFragmentManager().beginTransaction().replace(R.id.container_view_on_main, Fragment1.newInstance());

使用 getChildFragmentManager()

首先,我们必须创建一个ID为container_view_on_fragment1inside的布局fragment1.xml,然后

getChildFragmentManager().beginTransaction().replace(R.id.container_view_on_fragment1, Fragment2.newInstance()).commit();

结论

在本演示中,我觉得我们应该用getFragmentManager()从去的时候Fragment1Fragment2,因为它是简单和良好的性能(Fragment1将停止时Fragment2打开)

什么时候使用getChildFragmentManager()
例如你MainActivity有一个ViewPager包含3页的,每个页面内您需要替换一些片段。

更多
-getParentFragment()
getFragmentManager() =>返回null
getChildFragmentManager() =>总是返回根片段(Fragment1在演示中,即使我们转到Fragment3 ,, ...)

这个答案是基于我的理解,如果我错了,请纠正我。希望对你有帮助


2

如果要具有充当片段容器的片段,则必须使用该片段的getChildFragmentManager方法。如果使用getSupportFragmentManager,则基本上将使用片段管理器,该片段管理器的行为方式与活动生命周期不同,而不是片段的行为方式。

例如,我有一个包含ViewPager的片段–它称为CollectionsFragment。所以我在其中显示了3个片段作为选项卡:AllCollectionsFragment,MyCollectionsFragment,FavouriteCollectionsFragment。然后,我将getActivity()。getSupportFragmentManager()提供给了我正在使用的FragmentStatePagerAdapter。

因此,这导致了以下行为–不调用3个选项卡片段的onDestroyView / onDestroy / onDetach / onStop方法。当我更改为使用getChildFragmentManager时,一切正常。

如果需要,可以检查文档中的两种方法:

getChildFragmentManager():返回一个私有的FragmentManager,用于在此Fragment中放置和管理Fragment。

getSupportFragmentManager():返回用于与与此片段的活动相关联的片段进行交互的FragmentManager。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.