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

时间:2013-02-06 22:54:15

标签: android android-fragments android-listfragment

我的类继承了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;
    }

}

3 个答案:

答案 0 :(得分:125)

getChildFragmentManager()的定义是:

  

返回私有FragmentManager以放置和管理碎片   在这片段中。

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

  

返回FragmentManager以与相关的片段进行交互   这个片段的活动。

基本上,区别在于Fragment现在有自己的内部FragmentManager可以处理碎片。子FragmentManager是处理仅包含在它所添加的Fragment中的Fragments的子类。另一个FragmentManager包含在整个Activity

在这种情况下,我猜测你已经将片段添加到Activity的FragmentManager中。您得到的子FragmentManager不包含您要查找的内容。因此,您得到异常,因为它找不到具有给定ID的Fragment,因为它位于不同的FragmentManager中。

答案 1 :(得分:11)

getFragmentManager属于Activity
getChildFragmentManager属于Fragment

示例我们的应用包含MainActivityFragment1Fragment2container_view_on_mainactivty_main.xml

中的布局

Fragment1上展示 MainActivity我们必须使用getSupportFragmentManager()

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

Fragment2显示 Fragment1我们有2路

USE getFragmentManager()

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

USE getChildFragmentManager()

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

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

<强>结论

在这个演示中,我认为从getFragmentManager()Fragment1时我们应该使用Fragment2,因为它很简单且对性能有益(Fragment1会在{Fragment2时停止1}}开放)

当我们使用getChildFragmentManager()时 示例MainActivity有一个ViewPager,其中有3页,在每个页面中需要替换一些片段。

更多
- getParentFragment()
getFragmentManager() =&gt; return null
getChildFragmentManager() =&gt;总是在demo中返回根片段(Fragment1,即使我们去Fragment3 ,, ...)

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

答案 2 :(得分:0)

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

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

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

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

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

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