Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to switch between two fragments

I'm interested in the best way to have a single activity that switches between two fragments.

I've read probably 15 Stack Overflow posts and 5 blogs posts on how to do this, and, while I think I cobbled together a solution, I'm not convinced it's the best one. So, I want to hear people's opinions on the right way to handle this, especially with regards to the lifecycle of the parent activity and the fragments.

Here is the situation in detail:

  1. A parent activity that can display one of two possible fragments.
  2. The two fragments have state that I would like to persist across a session, but does not necessarily need to be persisted between sessions.
  3. A number of other activities, such that the parent activity and the fragments could get buried in the back stack and destroyed due to low memory.
  4. I want the ability to use the back button to move between the fragments (So as I understand it, I can't use setRetainInstance).

In addition to general architecture advice, I have the following outstanding questions:

  1. If the parent activity is destroyed due to low memory, how do I guarantee that the states of both fragments will be retained, as per this post: When a Fragment is replaced and put in the back stack (or removed) does it stay in memory?. Do I just need a pointer to each fragment in the parent activity?
  2. What is the best way for the parent activity to keep track of which fragment it is currently displaying?

Thanks in advance!

like image 493
GLee Avatar asked Sep 25 '13 19:09

GLee


People also ask

How do I switch between fragments?

Use replace() to replace an existing fragment in a container with an instance of a new fragment class that you provide. Calling replace() is equivalent to calling remove() with a fragment in a container and adding a new fragment to that same container. transaction. commit();

How to switch between two fragments android studio?

if you want to be able to switch between those fragments with the Backbutton, you can catch the buttonClick for onBackPressed and handle it accordingly.

Is it possible to reuse a fragment in multiple screens?

Yes you can! Show activity on this post.

What is Findfragmentbytag?

This method allows you to retrieve the instance of a previously added fragment with the given tag regardless of the container it was added to.


2 Answers

I ended up adding both of the fragments using the support fragment manager and then using detach/attach to switch between them. I was able to use commitAllowingStateLoss() because I retain the state of the view elsewhere, and manually set the correct fragment in onResume().

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

    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.my_layout, new AFragment(), TAG_A);
    fragmentTransaction.add(R.id.my_layout, new BFragment(), TAG_B);
    fragmentTransaction.commit();
}

public void onResume() {
    super.onResume();
    if (this.shouldShowA) {
        switchToA();
    } else {
        switchToB();
    }
}

private void switchToA() {
    AFragment fragA = (AFragment) getSupportFragmentManager().findFragmentByTag(TAG_A);
    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.detach(getSupportFragmentManager().findFragmentByTag(TAG_B));
    fragmentTransaction.attach(fragA);
    fragmentTransaction.addToBackStack(null);

    fragmentTransaction.commitAllowingStateLoss();
    getSupportFragmentManager().executePendingTransactions();
}
like image 134
GLee Avatar answered Oct 12 '22 00:10

GLee


You might want to consider using a ViewPager in your parent Activity so you can switch between the Fragments.

So you would be able to swipe through them.

if you want to persist their state during a session even if the parent activity is destroyed, you need to make them Parcelable, so you can save the state even if the class isn't instantiated at that time. You also need to do this if your rotating your device and want to keep the current situation/data on the Screen.

You should write them to a Parcelable in their onPause methods and recreate them from it in the onResume one. This way it doesn't matter if they are destroyed or have to be recreated due to changes in the devices orientation.

if you want to be able to switch between those fragments with the Backbutton, you can catch the buttonClick for onBackPressed and handle it accordingly.

If you need to figure out what Fragment your displaying at a given time you ask your ViewPager what Fragment he is displaying at that time, so you don't have to keep track, you can just ask someone who knows, if you need to know it.

like image 20
Daniel Bo Avatar answered Oct 12 '22 00:10

Daniel Bo