What is difference between getSupportFragmentManager() and getChildFragmentManager()?

AndroidAndroid FragmentsAndroid Listfragment

Android Problem Overview


My class inherits Fragment and that's why it can't use getSupportFragmentManager(). I am using getChildFragmentManager and it is showing me Error - IllegalArguementException: No view found for id... error.

Any guidance would be appreciated.

Code for calling AttachmentsListFragment is

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 is

<?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;
	}

}

Android Solutions


Solution 1 - Android

The definition of getChildFragmentManager() is:

> Return a private FragmentManager for placing and managing Fragments > inside of this Fragment.

Meanwhile the definition of getFragmentManager() (or in this case getSupportFragmentManager()) is:

> Return the FragmentManager for interacting with fragments associated > with this fragment's activity.

Basically, the difference is that Fragment's now have their own internal FragmentManager that can handle Fragments. The child FragmentManager is the one that handles Fragments contained within only the Fragment that it was added to. The other FragmentManager is contained within the entire Activity.

In this case, what I'm guessing is you've added the Fragments to the Activity's FragmentManager. You get the child FragmentManager which doesn't contain what you are looking for. Thus you get the exception because it can't find the Fragment with the given ID because it's in a different FragmentManager.

Solution 2 - Android

getFragmentManager belong to Activity
getChildFragmentManager belong to Fragment

Example we have a app which have MainActivity, Fragment1, Fragment2, container_view_on_main is a layout in activty_main.xml

TO display Fragment1 on MainActivity we must use getSupportFragmentManager()

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

TO display Fragment2 from Fragment1 we have 2 way

USE getFragmentManager()

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

USE getChildFragmentManager()

First, we have to create a layout with id container_view_on_fragment1 inside fragment1.xml, then

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

CONCLUSION

In this demo, I think we should use getFragmentManager() when go from Fragment1 to Fragment2 because it is simple and good for performance (Fragment1 will stop when Fragment2 open)

When we use getChildFragmentManager()?
Example your MainActivity have a ViewPager which have 3 pages, inside each pages you need to replace some fragment.

MORE
- getParentFragment()
getFragmentManager() => return null
getChildFragmentManager() => always return root fragment (Fragment1 in demo even we go to Fragment3,,... )

This answer is base on my understand so please correct me if I am wrong. Hope it help

Solution 3 - Android

If you want to have a fragment which behaves as a container of fragments you must use the getChildFragmentManager method of the fragment. If you use the getSupportFragmentManager you will basically use the fragment manager which behaves the way the activity lifecycle goes, not the way your fragment does.

For example I had a fragment which contained a ViewPager – it is called CollectionsFragment. So I had 3 fragments displayed as tabs in it: AllCollectionsFragment, MyCollectionsFragment, FavouriteCollectionsFragment. And I gave the getActivity().getSupportFragmentManager() to the FragmentStatePagerAdapter which I was using.

So this was causing the following behavior – the onDestroyView/onDestroy/onDetach/onStop methods of the 3 tab fragments not to be called. When I changed to use the getChildFragmentManager everything was OK.

If you want you can check the docs for the two methods:

getChildFragmentManager(): Return a private FragmentManager for placing and managing Fragments inside of this Fragment.

getSupportFragmentManager(): Return the FragmentManager for interacting with fragments associated with this fragment’s activity.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNinjaCoderView Question on Stackoverflow
Solution 1 - AndroidDeeVView Answer on Stackoverflow
Solution 2 - AndroidLinhView Answer on Stackoverflow
Solution 3 - AndroidVinod PattanshettiView Answer on Stackoverflow