1

I'm very confused. Here it says:

nested fragments as shown in the screenshot are not possible without the support library.

and also here they said:

AFAIK, fragments cannot hold other fragments.

All this are confirmed by the Android Documentation here. So that means one thing:

You can't put Fragments into Fragments without Support v4 Library on pre API 17!

Ok, but when I have the following settings: build.gradle

apply plugin: 'com.android.application'


android {
    compileSdkVersion 16
    buildToolsVersion '19.1.0'

    defaultConfig {
        applicationId "package.supportfragments"
        minSdkVersion 14
        targetSdkVersion 16
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

MainActivity:

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    getFragmentManager().beginTransaction().add(R.id.frame_test, new TestFragment()).commit();
}

TestFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_test, container, false);

    getFragmentManager().beginTransaction().add(R.id.frame_test_2, new TestNestedFragment()).commit();

    return rootView;
}

TestNestedFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_test_nested, container, false);

    getFragmentManager().beginTransaction().add(R.id.frame_test_3, new TestNestedNestedFragment()).commit();

    return rootView;
}

The Layout looks all like that:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

   <!-- TODO: Update blank fragment layout -->
   <FrameLayout
       android:id="@+id/IDTOTHEFRAGMENT"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

</FrameLayout>

And it works like a charme... The question is.. WHY??!!

Community
  • 1
  • 1
StefMa
  • 3,344
  • 4
  • 27
  • 48
  • 1
    *The question is.. WHY??!!* - As Darius Janušauskas already pointing out, making those transaction with the FragmentManager of the activity inside another fragment doesn't make the fragments nested(using getChildFragmentManager() makes them nested). That would be like doing a fragment transaction inside a sub class of SQLiteOpenHelper and saying that the fragments are embedded in the SQLiteDatabase. – user Jan 12 '15 at 12:18

2 Answers2

3

Your example doesn't nest the fragment. When calling getFragmentManager() from the fragment it returns the activities FragmentManager, so you are adding fragments to the activity.

To add nested fragments you need to use getChildFragmentManager() which was introduced in API 17 so you cant use it if you don't use the support fragment implementation.

Sufiyan Ghori
  • 18,164
  • 14
  • 82
  • 110
  • It doesn't nested?! Nested means a Fragment in a Fragment, right?! The example make that. A Fragment in a Fragment == Nested... or not?! €dit: These example http://stackoverflow.com/questions/13757875/getchildfragmentmanager-on-programmatically-dynamically-added-fragments shows the same like my example. But with ChildFragmentManager... – StefMa Jan 12 '15 at 12:02
  • 1
    Maybe it compiles and runs but your code isn't nesting the second fragment it's just trying to add it to the activity. For nesting you need to use http://developer.android.com/reference/android/app/Fragment.html#getChildFragmentManager() – Darius Janušauskas Jan 12 '15 at 12:06
  • But this is exactly the question! Why it compiles and run without ChildFragmentManager, when it is the behavior to be nested. – StefMa Jan 12 '15 at 12:08
  • Because the fragments getFragmentManager() returns the activities FragmentManager, so it's the same as adding your fragment from the activity. In other words your app is launching an activity, adding a fragment to that activity, and then the new fragment adds one more fragment to the activity. The key is the FragmentManager, in your case you need the one provided by getChildFragmentManager(), otherwise you are just adding fragments to the activity. – Darius Janušauskas Jan 12 '15 at 12:16
  • 1
    @StefMa: "The example make that" -- no, it does not. It simply creates *another* fragment that is a peer of the first one. The second fragment is not nested inside of the first one. Moreover, your app will start to behave *very* strangely if you stick with your existing code, particularly as you start trying to `replace()` or `remove()` fragments. – CommonsWare Jan 12 '15 at 12:17
  • Ah ok.. thank you all. But when it's time to use the getChildFragmentManager?! – StefMa Jan 12 '15 at 12:25
1

Here the activity is having two fragments and you are adding both, thats correct. But since you add() another fragment inside a fragment that doesnt mean the whole thing is nested, You are using the getFragmentManager() in both senario which will always refer to the activity.

Nested Fragment senario:

Consider that FragmentA is having a viewpager with 3 swipable fragments and you are adding FragmentA to the activity. Here you can say the viewpager fragments are nested because you are having a fragment inside FragmentA and must use getChildFragmentManager() to add the 3 fragments to view pager.

Update:

I have gone though the android source code and there it is clearly mentioned

"Return the FragmentManager for interacting with fragments associated with this fragment's activity. Note that this will be non-null slightly before getActivity(), during the time from when the fragment is placed in a FragmentTransaction until it is committed and attached to its activity. If this Fragment is a child of another Fragment, the FragmentManager returned here will be the parent's getChildFragmentManager()".

droid kid
  • 7,569
  • 2
  • 32
  • 37
  • But it is the beter (or the right?) way to use always getChildFragmentManager() when a fragment is in the layout from another fragment?! – StefMa Jan 12 '15 at 13:16
  • I faced some issues when I use getFragmentManager() inside viewpager (I did before API_17) and in the android source code its is clearly mentioned to use childmanager()...check my updated answer – droid kid Jan 12 '15 at 13:29