Move Android fragment to another container. Unable to change fragment container identifier.

Here is what I would like my app to do on the tablet. In fragment (0) there is a menu in which fragments (1) ... (n) will be displayed as follows:

----------------- | | | | | | | | | | |(0)| X | X | X | | | | | | | | | | | ----------------- becomes ----------------- | | | | | | | | | | |(0)|(1)| X | X | | | | | | | | | | | ----------------- and then ----------------- | | | | | | | | | | |(0)|(2)|(1)| X | | | | | | | | | | | ----------------- etc... 

Fragment0 never moves, others shift to the right. Fragments emerging from the edge to the right will be destroyed.

So, I am setting up my XML layout with a horizontal LinearLayout and containing 4 FrameLayout with the corresponding identifiers (fragment 0 ... fragment3)

I can create an instance and display fragment 0 and then fragment1, but after that I cannot move it to the right, I get:

 ERROR/AndroidRuntime(343): FATAL EXCEPTION: main java.lang.IllegalStateException: Can't change container ID of fragment ... 

The only related questions that I found are this one and that one , tried all the different solutions offered with no luck.

I tried FragmentTransaction.remove() , and then .add() , tried .replace() , tried them in different orders and committed halfway (even tried to do twice as much as someone suggested), tried to call addToBackStack() ... still no luck.

The question is whether fragments like this can be moved using FragmentTransaction. If so, what am I doing wrong (and a bonus, can this be revived?). If not, what would be the right way to implement this?

Please note that I do not want to recreate fragments every time (each of them performs some queries on the Internet, which may take some time). It can retrieve all the data back for activity in order to recreate one, but I would rather not do this if it were possible ...

+7
source share
2 answers

I don’t know, this is what you want, but I made a small example of your problem. Basically, you'll do the right move with the layout file, having a wrapper container for each of these shifting fragments. The sample code is a bit big for an answer, so I posted it in the one you can find here . In this example, click each of the ListFragment elements (fragment 1 β†’ fragment 2 β†’ fragment 3) to see the behavior.

+3
source

Yes, the fragment container can be changed using the remove() function.

The problem here is commit() . This is an asynchronous call and will schedule it in the main thread. Therefore, to force the FragmentManager to do this just before adding it to another container.

To do this, we will need to use the executePendingTransactions() function. After calling this attempt, add the fragment to the new container.

Documents: executePendingTransactions ()

Code example:

 FragmentManager fManager = getSupportFragmentManager(); FragGroups fragGroups = (FragGroups) fManager.findFragmentByTag("groups"); if (fragGroups != null) { fManager.beginTransaction().remove(fragGroups).commit(); fManager.executePendingTransactions(); } else { fragGroups = new FragGroups(); } if (mTwoPane) { fManager.beginTransaction().replace(R.id.fragment_container_groups, fragGroups, "groups").commit(); } else { fManager.beginTransaction().replace(R.id.fragment_container, fragGroups, "groups").commit(); } 

Enjoy. Feedback is welcome

Edit

I would like to add an item here. Since I had the same problem, she got into this thread and applied the proposed changes. The problem still persists. Then I looked at the last comment on this topic that solved my problem: remove the addToBackStack() method when making a transaction or, if you intentionally use it, remove the fragment from the previous stack before adding it to another container. Hope this helps the future reader.

+20
source

All Articles