HawkForce
HawkForce

Reputation: 171

Android Fragment is given a null container in onCreateView()

I am trying to use Android fragments in a very simple way, similar to the tutorial on the Android developer website.

I have an Activity (MediaInfoActivity) with the following code:

public class MediaInfoActivity extends FragmentActivity {
    private final String TAG = "MediaInfoActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate()");
        setContentView(R.layout.media_info_activity_layout);
    }

}

Here is the code for the media_info_activity_layout.xml file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
    android:orientation="vertical">

    <fragment class="com.hawkforce.test.MediaInfoFragment"
            android:id="@+id/mediaInfoFragment"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="0dp" />

    <FrameLayout android:id="@+id/mediaPlayerBarPanel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

    <fragment class="com.hawkforce.test.MediaPlayerBarFragment"
                android:id="@+id/mediaPlayerBar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

    </FrameLayout>

And finally here is the code for MediaInfoFragment:

public class MediaInfoFragment extends Fragment {
    private final static String TAG = "MediaInfoFragment";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate()");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        Log.i(TAG, "onCreateView()");
        if (container == null) {
            Log.i(TAG, "onCreateView(): container = null");
        }

        return inflater.inflate(R.layout.media_info_fragment_layout, container, false);
    }

}

Here is my problem : the container passed in the onCreateView() method of the MediaInfoFragment is null. As I understood, this should only be the case for non-UI Fragments. However, my Fragment has a UI, which is displayed OK on the screen when I launch MediaInfoActivity. It causes problems because no style declared in the xml layout file of the fragment is applied.

Here is my Log:

I/MediaInfoActivity: onCreate()
I/MediaInfoFragment: onCreate()
I/MediaInfoFragment: onCreateView()
I/MediaInfoFragment: onCreateView(): container = null

Am I missing anything obvious here ?

Upvotes: 17

Views: 9204

Answers (2)

Namdev Londhe
Namdev Londhe

Reputation: 111

You just have to create a inflater like bellow in your fragment.

View rootView;
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    if (rootView == null) {
        rootView = inflater.inflate(R.layout.activity_my_cart, null);
    } else {
        ((ViewGroup) container.getParent()).removeView(rootView);
    }
    return rootView;
}

I hope it will work as per your question.

Upvotes: 3

Gilad
Gilad

Reputation: 759

I am not sure since I don't have the code of the SDK in front of me but I think that the life-cycle of calling Fragment "onCreateView" function is different between the two cases: 1. Static settings of fragment in layout 2. Loading pragmatically with FragmentManager.

In the first case the debugger get into Fragment.onCreateView() method immediately upon adding the content view to the parent activity as part of onCreate() code:

When calling: setContentView(R.layout.some_layoue); You will see the debugger get into Fragment.onCreateView() before going to next line

In the second case the Fragment.onCreateView() is being invoked only after the onCreate() of the activity is finished.

This looks like design bug for me but possibly as design feature. Anyway the container is null when adding fragment statically because the related object was not yet created.

In fact the difference between the two situations is much deeper. In the case of static fragments toggling between fragments will not create the view hierarchy correctly.

For example if you will add button-A to fragment A and button-B to Fragment-B and toggle the fragments with a code looks like this (highlighting only the relevant code):

public void turnOnFragment() {
    FragmentManager manager = getFragmentManager();
    if (manager != null) {
        manager.beginTransaction()
                .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
                .attach(this)
                .commit();
    }
}



public void turnOffFragment() {
    FragmentManager manager = getFragmentManager();
    if (manager != null) {
        manager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        manager.beginTransaction()
                .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
                .detach(this)
                .commit();


    }
}

You will see that in the case of static fragments the buttons from both fragments are presented although turning on and off. If however fragments are added programatically the toggle works fine and view hierarchy is cleaned and show only button from relevant fragment.

This is based of my experience with version 4.4.2

Upvotes: 2

Related Questions