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

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

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.

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

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.

Related

Nested fragments - fragment started from a fragment does not inflate the layout xml

I am trying nested fragment because my xml layout starts to be difficult to maintain.
From a fragment I start a fragment when I click on the skip button. I tried both a normal start and a child fragment. On both case I get into the fragment in the inflate method but my screen stays empty. Of course when I call the fragment as a first level the layout inflates correctly.
Call to the 2nd fragment within the 1st one:
skip.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
SelectServiceFragment ssf = new SelectServiceFragment();
ft.add(ssf,"SelectService");
ft.commit();
}
});
SelectServiceFragment:
public class SelectServiceFragment extends Fragment {
Context context;
public SelectServiceFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootview = null;
rootview = inflater.inflate(R.layout.select_svce_fragment, container, false);
return rootview;
}
and my xml layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Select service!!!!"
android:textColor="#000000"
/>
</RelativeLayout>
Did I miss something in nested fragments?
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
SelectServiceFragment ssf= new SelectServiceFragment();
fragmentTransaction.add(R.id.fragment_container, ssf, "SelectService");
fragmentTransaction.commit();
try this way
Yes, you are missing the most important thing. that you can change fragment from the base class method. the class in which you first replace method. make that method as a public method and pass it parameters with fragment class name. Let say you have method in base class where you first replace or initiate fragment
public void replaceFragment( Fragment fragment) {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content_home, fragment);
fragmentTransaction.commit();
// if you have used drawer_layout
// othere wise no need of below lines
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
then call this method in any fragment and pass the fragment class name like this ((BaseClassName) getActivity()).replaceFragment(new ReportLostItem()); this way you will be able to replace the fragment from any fragment class. accept the answer if it solves your problem
My excuses guys for having you lose your time on this!
All is working as expected!
the only thing I was doing as I was jumping from RelativeLayout is setvisibility(invisible) on the RL where the framelayout is.
Sorry!

Android: how to add another fragment to the main activity

I asked a question about how to add a Fragment that contained something drawn using OpenGL ES
here. Someone was kind enough to answer that for me, but unfortunately today I encountered another problem. As I mentioned in my other question, my purpose is to add other Fragments next to the one that contains OpenGL and because I am a beginner in Android development I don't seem to understand how this is done.
Here's what I want: right now, my code is exactly the one from my other question. I also have this Fragment:
public class TextFragment extends Fragment
{
private TextView textview;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.text_fragment,
container, false);
textview = (TextView) view.findViewById(R.id.textView1);
return view;
}
}
together with its layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frag2">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Fragment Two"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
and I want to add this to my main activity, where right now I only have the OpenGL Fragment. Here's my main activity:
public class FragmentExampleActivity extends FragmentActivity implements ToolbarFragment.ToolbarListener
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener()
{
public void onBackStackChanged()
{
int backCount = getSupportFragmentManager().getBackStackEntryCount();
if (backCount == 0)
{
finish();
}
}
});
if (savedInstanceState == null)
{
getSupportFragmentManager()
.beginTransaction()
.add(R.id.main_container, new OpenGLES20ActivityFrag())
.addToBackStack(null)
.commit();
}
}
}
and the Fragment that has OpenGL in it and that I have already added to the main activity:
public class OpenGLES20ActivityFrag extends Fragment
{
private GLSurfaceView mGLView;
public OpenGLES20ActivityFrag()
{
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
mGLView = new MyGLSurfaceView(this.getActivity());
return mGLView;
}
}
What I tried and failed: using another call to the .add method inside getSupportFragmentManager() or adapting this bit of code for my second Fragment
getSupportFragmentManager()
.beginTransaction()
.add(R.id.frag2, TextFragment)
.addToBackStack(null)
.commit();
that gave me an 'expression expected' error in the add method. I tried adding this constructor to my second Fragment
public TextFragment()
{
super();
}
and then inside the add method I put .add(R.id.frag2, new TextFragment())
which still didn't work.
In order to dynamically add a Fragment to a layout, what you need is a container (like in your case, it was R.id.main_container). Thus, if you want to add multiple fragments, what you need is multiple containers, like so:
<LinearLayout android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent">
<FrameLayout android:id="#+id/main_container_1" android:layout_weight="1" android:layout_height="fill_parent" android:layout_width="fill_parent"/>
<FrameLayout android:id="#+id/main_container_2" android:layout_weight="1" android:layout_height="fill_parent" android:layout_width="fill_parent"/>
</LinearLayout>
(this snippet is from How to split the screen with two equal LinearLayouts? )
And then you would need to add the two Fragments:
if (savedInstanceState == null)
{
getSupportFragmentManager()
.beginTransaction()
.add(R.id.main_container_1, new OpenGLES20ActivityFrag())
.commit();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.main_container_2, new TextFragment())
.commit();
}
Please note that with multiple Fragments on a single Activity, it's better not to add them to the backstack, because then you'd have to press Back as many times as there are Fragments, and in this case it's more reasonable to navigate between the "views" or states of the application with Activities, and not by replacing the Fragments.
(considering the backstack doesn't change, I don't think the backstack listener needs to be removed, but that's done so that if you press Back, you don't end the Activity, but the Fragments within it first if you have them added to the backstack. But the Activity doesn't end when it contains no fragments, and you'd have an "empty view", hence why that was added.)
Please also check if the rotation works and data is maintained even after the activity reconstruction, because there's a chance you need to set the retain instance state to true explicitly on the Fragments for that to work.

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 ?
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.
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

ViewPager isn't loading the items after removed and re-added into FrameLayout

I'm trying to make a fragment to display tips for the user. The fragment's createView method returns a ViewPager and setup the PagerAdapter through AsyncTask. This fragment is added dinamically in the FragmentActivity when the user press a button. If the user reaches the last item of press the same button again, this fragment is removed from the FragmentActivity. It's important to note that I add the fragment to the FrameLayout idenfified by android.R.id.content.
Ok, the first time I press the button, it works as expected. But the second time I press the button, the ViewPager doesn't appear. When I use the View Hierarchy to see what's happenning, I see the ViewPager in the right place, but with no items. I debugged and noted that the getCount() of the PagerAdapter is called, but the getItem is never called.
This is the createView method of my fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View tipsView = inflater.inflate(R.layout.tip_manager_layout, container, false);
this.tipPagerAdapter = new TipPagerAdapter(getFragmentManager(), getArguments().getIntArray(TIP_LAYOUT_IDS_KEY));
this.viewPager = (ViewPager) tipsView.findViewById(R.id.tip_pager);
this.viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
if(position == (tipPagerAdapter.getCount()-1)){
stop();
}
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
// Workaround to set the PagerAdapter within a fragment transaction
new SetViewPagerAdapterTask().execute();
return tipsView;
}
I add the fragment this way:
FragmentTransaction fragmentTransaction = fragmentActivity.getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(android.R.id.content, this, TAG);
fragmentTransaction.commit();
And remove the fragment this way:
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.remove(tipManagerFragment);
fragmentTransaction.commit();
This is the layout inflated by the fragment:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tip_pager"
android:layout_width="fill_parent"
android:layout_height="175dp"
android:layout_gravity="center_horizontal|bottom"
android:paddingBottom="2dp" />
Could someone help me with this problem?
EDIT:
For a while, I'm using the show and hide methods of the fragment after adding it to the activity. But it's not the correct approach. I can't understand why I can't add again a fragment with a ViewPager. The ViewPager is added and removed correctly, but the second time, it simply doesn't show anything.
After a long time thinking about my problem, I had the following idea: maybe the problem is related to the fact that I'm removing the fragment that has the ViewPager, but I'm not removing the fragments used by the ViewPager. Then, these fragments continues in the FragmentManager and something strange happens when the new ViewPager tries to use them.
So, I started trying to remove all the fragments. To do this, I created a method in my FragmentPagerAdapter this way:
public void destroy(FragmentTransaction fragmentTransaction){
for(Fragment tipFragment : tipFragments){
fragmentTransaction.remove(tipFragment);
}
}
The adapter is using the tipFragments to create its content. So, I get a fragmentTransaction as parameter and I remove all these fragments. When I want to remove my fragment, I use this code:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
tipPagerAdapter.destroy(fragmentTransaction);
fragmentTransaction.remove(TipManagerFragment.this);
fragmentTransaction.commit();
This way, I remove all the fragments and when I add the fragment which has the ViewPager again, everything works well.

Android - Viewpager and fragments, methods not working

I have a ViewPager with two Fragments which I instantiate in onCreate of my FragmentActivity.
private List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this,Frag_1.class.getName()));
fragments.add(Fragment.instantiate(this,Frag_2.class.getName()));
this.vPagerAdapter = new Adapt(super.getSupportFragmentManager(),fragments);
vPager = (ViewPager) super.findViewById(R.id.pager);
vPager.setAdapter(vPagerAdapter);
My second Fragment has a method inside that I call to update my ListView - refreshList():
public class Frag_2 extends Fragment {
private ListView list;
private ArrayList<data> data;
private boolean firstCreation=true;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRetainInstance(false);
}
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout, container, false);
list = (ListView) view.findViewById(R.id.lst);
//this.setRetainInstance(true);
return view;
}
public void refreshList(ArrayList <data> data){
if(data!=null){
ArrayAdapter<data> adapter = new Item_data_adapter(getActivity(),data);
list.setAdapter(adapter);}
}
}
Called from my FragmentActivity
//Something
Frag_2 fr = (Frag_2) vPagerAdapter.getItem(1);
if (fr.getView() != null) {
fr.refreshList(data);
}
It works fine until I change the orientation of the screen. Correct me if I'm wrong, but I was searching for hours and I didn't find a solution or a good explanation, the FragmentActivity is created only one time and the Fragments are attached to it but the Fragments recreate on configuration changes.
Now, when the orientation changes I don't get the View from onCreateso when I try to get the View from the Fragment it returns null and my refreshList() method isn't called. How can I fix this?
I fixed the problem this way:
In the onCreate of the FragmentActivity
if(savedInstanceState!=null){
frag1 = (frag_1) getSupportFragmentManager().getFragment(savedInstanceState, frag_1.class.getName());
frag2 = (frag_2) getSupportFragmentManager().getFragment(savedInstanceState, frag_2.class.getName());
}
else{
frag1 = (frag_1) Fragment.instantiate(this,frag_1.class.getName());
frag2 = (frag_2) Fragment.instantiate(this,frag_2.class.getName());
}
fragments.add(frag1);
fragments.add(frag2);
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, frag_1.class.getName(), frag1);
getSupportFragmentManager().putFragment(outState, frag_2.class.getName(), frag2);
}
Maybe it's not the best solution in the universe, but it looks like it works...
When u want to refresh the List do something like this :
public void setView() {
Frag_2 fr = (Frag_2) vPagerAdapter.getItem(1);
fragmentManager.beginTransaction().detach(fr).commit();
fragmentManager.beginTransaction().attach(fr).commit();
}
If you are using a dynamic fragment, you need to test first to prevent creating a second instance of a fragment.
To test whether the system is re-creating the activity, check whether the Bundle argument passed to your activity’s
onCreate() is null.
If it is non-null, the system is re-creating the activity. In this case, the activity automatically re-instantiates existing
fragments.
If it's null you can safely instantiate your dynamic fragment. For example:
public void onCreate(Bundle savedInstanceState) {
// ...
if (savedInstanceState != null) {
FragmentManager fragmentManager = getFragmentManager()
// Or: FragmentManager fragmentManager = getSupportFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
}
The Fragment class supports the onSaveInstanceState(Bundle) method (but not the onRestoreInstanceState() method) in much the same way as the Activity class.
The default implementation saves the state of all the fragment’s views that have IDs.
You can override this method to store additional fragment state information.
If the system is re-creating the fragment from a previous saved state, it provides a reference to the Bundle containing that state to the onCreate(), onCreateView(), and onActivityCreated() methods; otherwise, the
argument is set to null.
If you want a detailed info, here's a good talk by Ken Jones of Marakana

Categories

Resources