0

I have searched for this question and it seems that such questions have not been asked yet.

What I have

An app that has three fragments that are added through java code (without <frgament> </fragment>). All three fragments are displayed together when the device is in landscape mode. In portrait mode, on the other hand, only one is displayed. The fragment that is displayed in the portrait mode has a button. If that button is pressed, an event is triggered that informs the listener ( main activity in my case) which in turn replaces the fragment with another one. Everything takes place in one activity.

Here is the onCreate() from the activity:

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

     //depending on the orientation this layout file is different. 
     setContentView(R.layout.fragment_layout);

     //landscapeCase
     if (getResources().getConfiguration().orientation
             == Configuration.ORIENTATION_LANDSCAPE) {


         //adding three fragments into their places

         FragmentManager fragMgr = getFragmentManager();


         FragmentTransaction xact = fragMgr.beginTransaction();

         if(fragMgr.findFragmentByTag(FRAG1_TAG)==null){

             xact.add(R.id.frame1,new AddNoteFragment(), FRAG1_TAG );
         }

         if(fragMgr.findFragmentByTag(FRAG2_TAG)==null){

             xact.add(R.id.frame2,new ListNoteFragment(), FRAG2_TAG );

         }

         if(fragMgr.findFragmentByTag(FRAG3_TAG)==null){
             xact.add(R.id.frame3,new DetailNoteFragment(), FRAG3_TAG );

         }


         xact.commit(); 

     }

     //portrait case
     if (savedInstanceState == null) {


         FragmentManager fragMgr = getFragmentManager();


         FragmentTransaction xact = fragMgr.beginTransaction();

         if(fragMgr.findFragmentByTag(FRAG1_TAG)==null){
             xact.add(R.id.frame1,new AddNoteFragment(), FRAG1_TAG );   
         }
         xact.commit();

     }
 }

Here is the OnPressed method that handles the button press from the fragment in the portrait case:

   //frame1, frame2 and frame3 are the layouts inside (fragment_layout.xml) that are dedicated to the              //fragments.
   //in portrait mode only frame1 is available.
    @Override
        public void OnPressed(String TAG) {
            if(TAG.equals("frag1") && getResources().getConfiguration().orientation
                    == Configuration.ORIENTATION_PORTRAIT){



            FragmentManager fragMgr = getFragmentManager();  
             FragmentTransaction xact = fragMgr.beginTransaction();

            if(fragMgr.findFragmentByTag(FRAG2_TAG)==null) {

                xact.replace(R.id.frame1, new ListNoteFragment(), FRAG2_TAG);
                 }

            else {
                //problem occurs here.
                xact.replace(R.id.frame1, fragMgr.findFragmentByTag(FRAG2_TAG));

                }
            xact.addToBackStack(null);
            xact.commit();

            }

            }

The Problem

The process of replacing the fragments works (including the back button) when strictly in portrait mode. However, if I switch to landscape and then back to portrait and then press the button everything crashes ( IllegalStateException: Can't change container ID of Fragment ).

The problem stems from here:

if(fragMgr.findFragmentByTag(FRAG2_TAG)==null) {

                xact.replace(R.id.frame1, new ListNoteFragment(), FRAG2_TAG);
                 }

            else {
                //problem occurs here.
                xact.replace(R.id.frame1, fragMgr.findFragmentByTag(FRAG2_TAG));

                }

After the rotation occurs , fragment with FRAG2_TAG is created and as a result when going back to the portrait case and pressing the button, the else part is executed. For some reason "it" does not like the idea of retrieving already created fragment. Interestingly, when I get rid of else and only keep the upper part everything works well. For some reason it works when I create new fragments but does not when I ask it to reuse the old one.

Questions

Can anyone explain why it does not allow me to reuse the already created fragment ?

Is it possible to create only three fragments so that they can be shown together in landscape mode and switched in between in portrait (all in single activity ) ?

Some big picture ideas regarding reusing fragments will be much appreciated.

My apologies for such lengthy post.

372
  • 237
  • 2
  • 10

1 Answers1

1

You can reuse the already created fragment. The reason it crashes is because the fragment will try to recreate itself. You have to check if the fragment is already there. Here is the solution to your problem:

https://stackoverflow.com/a/9646622/2767703

This guy explains it perfectly.

Hope this helps!

Community
  • 1
  • 1
Kevin van Mierlo
  • 9,554
  • 5
  • 44
  • 76
  • Thanks for the link. I did use findByTag for reobtaining references to the already created fragments. But for some reason it still does not work... – 372 Jan 30 '14 at 17:00