Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fragment lifecycle : onCreateView() not called when using back button

EDIT : after some experimentation, it looks like it works as expected if I don't add the initial fragment in the xml layout. I am now doing it in my activity source code. I suppose this is how I was expected to do it ?

According to http://developer.android.com/guide/components/fragments.html#Creating , if a fragment is removed and then added back, onCreateView() should be called.

I also can see that getView() returns null. onDestroyView() is called but the interface of my first fragment is still displayed when back is pressed

here is the result of my sample code :

--launch app
I/System.out( 3765): ==== FRAGMENT1.ONCREATE
I/System.out( 3765): ==== FRAGMENT1.ONCREATEVIEW
I/System.out( 3765): ==== FRAGMENT1.ONACTIVITYCREATED (FRAGMENT1.getView = android.support.v4.app.NoSaveStateFrameLayout@41301268

--second fragment
I/System.out( 3765): ==== FRAGMENT2.ONCREATE
I/System.out( 3765): ==== FRAGMENT2.ONCREATEVIEW
I/System.out( 3765): ==== FRAGMENT2.ONACTIVITYCREATED

--back is pressed : getView() == null and onCreateView is not called
I/System.out( 3765): ==== FRAGMENT1.ONACTIVITYCREATED (FRAGMENT1.getView = null

In case I am doing something wrong, here is some basic code to reproduce my issue :

my 2 fragment classes :

package com.test.testbackfragment;

import android.support.v4.app.Fragment;
import android.view.ViewGroup;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

public class Fragment1 extends Fragment {
    @Override
    public void onCreate(Bundle savedInstanceState)  {
        System.out.println("==== FRAGMENT1.ONCREATE");
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {    
        System.out.println("==== FRAGMENT1.ONCREATEVIEW");
        View v = inflater.inflate(R.layout.fragment1, container, false);

        v.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    getActivity().getSupportFragmentManager().beginTransaction()
                        .remove(Fragment1.this)
                        .add(R.id.fragment, new Fragment2())
                        .addToBackStack(null)
                        .commit();
                }
            });
        return v;
    }        

    @Override
    public void onActivityCreated (Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        System.out.println("==== FRAGMENT1.ONACTIVITYCREATED (FRAGMENT1.getView = "+getView());
    }    
}

and

package com.test.testbackfragment;

import android.support.v4.app.Fragment;
import android.view.ViewGroup;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

public class Fragment2 extends Fragment {
    @Override
    public void onCreate(Bundle savedInstanceState)  {
        System.out.println("==== FRAGMENT2.ONCREATE");
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {    
        System.out.println("==== FRAGMENT2.ONCREATEVIEW");
        View v = inflater.inflate(R.layout.fragment2, container, false);
        return v;
    }        

    @Override
    public void onActivityCreated (Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        System.out.println("==== FRAGMENT2.ONACTIVITYCREATED");
    }    
}

main activity is very simple

package com.test.testbackfragment;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MainActivity extends FragmentActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

and here are the 3 layouts : main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    <fragment android:name="com.test.testbackfragment.Fragment1"
            android:id="@+id/fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
</LinearLayout>

fragment1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" 
        android:background="#0000FF">
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="20dip"
            android:text="THIS IS FRAGMENT1" />

    <Button
            android:id="@+id/button"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" 
            android:textSize="20dip"
            android:text="FRAGMENT2"/>
</LinearLayout>

fragment2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" 
        android:background="#00FF00">
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="20dip"
            android:text="THIS IS FRAGMENT2" />
</LinearLayout>
like image 745
medmed Avatar asked Nov 13 '22 04:11

medmed


1 Answers

When the system creates this main.xml layout, it instantiates fragment specified in the layout and calls the onCreateView() method, to retrieve each fragment's layout. later on it will use same fragment instantiates. So, it won't call OnCreateView again.

If you want to create again, get an instance of FragmentTransaction from your Activity and implement as you like.

FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction .replace(R.id.fragment, newFragment);
// Commit the transaction
transaction.commit();
like image 109
Harsha Vardhan Avatar answered Nov 15 '22 00:11

Harsha Vardhan