I\'m wondering if this is actually a bug in the Android API:
I have a setup like so:
┌----┬---------┐
| | |
| 1 | 2 |
| |┌------
If you find your nested fragment not being removed or being duplicated (eg. on Activity restart, on screen rotate) try changing:
transaction.add(R.id.placeholder, newFragment);
to
transaction.replace(R.id.placeholder, newFragment);
If above doesn't help, try:
Fragment f = getChildFragmentManager().findFragmentById(R.id.placeholder);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
if (f == null) {
Log.d(TAG, "onCreateView: fragment doesn't exist");
newFragment= new MyFragmentType();
transaction.add(R.id.placeholder, newFragment);
} else {
Log.d(TAG, "onCreateView: fragment already exists");
transaction.replace(R.id.placeholder, f);
}
transaction.commit();
Learnt here
I've faced with the same problem, have struggled a couple of day with it and should say that the most easiest way to overcome I found this is to use fragment.hide() / fragment.show() when tab is selected/unselected().
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft)
{
if (mFragment != null)
ft.hide(mFragment);
}
When screen rotation occurs all parent and child fragments get correctly destroyed.
This approach has also one additional advantage - using hide()/show() does not cause fragment views to loose their state, so there is no need to restore the previous scroll position for ScrollViews for example.
The problem is that I don't know whether it is correct to not detach fragments when they are not visible. I think the official example of TabListener is designed with a thought in mind that fragments are reusable and you should not pollute with them memory, however, I think if you have just a few tabs and you know that users will be switching between them frequently it will be appropriate to keep them attached to the current activity.
I would like to hear comments from more experienced developers.
Nested fragments are not currently supported. Trying to put a fragment within the UI of another fragment will result in undefined and likely broken behavior.
Update: Nested fragments are supported as of Android 4.2 (and Android Support Library rev 11) : http://developer.android.com/about/versions/android-4.2.html#NestedFragments
NOTE (as per this docs): "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."
.. you can cleanup your nested fragment in the parent fragment's destroyview
method:
@Override
public void onDestroyView() {
try{
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.remove(nestedFragment);
transaction.commit();
}catch(Exception e){
}
super.onDestroyView();
}
I have an application that I am developing that is laid out similar with Tabs in the Action Bar that launches fragments, some of these Fragments have multiple embedded Fragments within them.
I was getting the same error when I tried to run the application. It seems like if you instantiate the Fragments within the xml layout after a tab was unselected and then reselected I would get the inflator error.
I solved this replacing all the fragments in xml with Linearlayouts and then useing a Fragment manager/ fragment transaction to instantiate the fragments everything seems to working correctly at least on a test level right now.
I hope this helps you out.
Nested fragments are supported in android 4.2 and later
The Android Support Library also now supports nested fragments, so you can implement nested fragment designs on Android 1.6 and higher.
To nest a fragment, simply call getChildFragmentManager() on the Fragment in which you want to add a fragment. This returns a FragmentManager that you can use like you normally do from the top-level activity to create fragment transactions. For example, here’s some code that adds a fragment from within an existing Fragment class:
Fragment videoFragment = new VideoPlayerFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.video_fragment, videoFragment).commit();
To get more idea about nested fragments, please go through these tutorials
Part 1
Part 2
Part 3
and here is a SO post which discuss about best practices for nested fragments.