get the latest fragment in backstack

140,932

Solution 1

You can use the getName() method of FragmentManager.BackStackEntry which was introduced in API level 14. This method will return a tag which was the one you used when you added the Fragment to the backstack with addTobackStack(tag).

int index = getActivity().getFragmentManager().getBackStackEntryCount() - 1
FragmentManager.BackStackEntry backEntry = getFragmentManager().getBackStackEntryAt(index);
String tag = backEntry.getName();
Fragment fragment = getFragmentManager().findFragmentByTag(tag);

You need to make sure that you added the fragment to the backstack like this:

fragmentTransaction.addToBackStack(tag);

Solution 2

FragmentManager.findFragmentById(fragmentsContainerId) 

function returns link to top Fragment in backstack. Usage example:

    fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            Fragment fr = fragmentManager.findFragmentById(R.id.fragmentsContainer);
            if(fr!=null){
                Log.e("fragment=", fr.getClass().getSimpleName());
            }
        }
    });

Solution 3

I personnaly tried many of those solutions and ended up with this working solution:

Add this utility method that will be used several times below to get the number of fragments in your backstack:

protected int getFragmentCount() {
    return getSupportFragmentManager().getBackStackEntryCount();
}

Then, when you add/replace your fragment using FragmentTransaction method, generate a unique tag to your fragment (e.g.: by using the number of fragments in your stack):

getSupportFragmentManager().beginTransaction().add(yourContainerId, yourFragment, Integer.toString(getFragmentCount()));

Finally, you can find any of your fragments in your backstack with this method:

private Fragment getFragmentAt(int index) {
    return getFragmentCount() > 0 ? getSupportFragmentManager().findFragmentByTag(Integer.toString(index)) : null;
}

Therefore, fetching the top fragment in your backstack can be easily achieved by calling:

protected Fragment getCurrentFragment() {
    return getFragmentAt(getFragmentCount() - 1);
}

Hope this helps!

Solution 4

Kotlin

// In activities
activity.supportFragmentManager.fragments.lastOrNull()

// In fragments
fragment.childFragmentManager.fragments.lastOrNull()

Solution 5

this helper method get fragment from top of stack:

public Fragment getTopFragment() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }
    String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return getSupportFragmentManager().findFragmentByTag(fragmentTag);
}
Share:
140,932

Related videos on Youtube

Leem.fin
Author by

Leem.fin

A newbie in software development.

Updated on July 08, 2022

Comments

  • Leem.fin
    Leem.fin about 2 years

    How can I get the latest fragment instance added in backstack (if I do not know the fragment tag & id)?

    FragmentManager fragManager = activity.getSupportFragmentManager();
    FragmentTransaction fragTransacion = fragMgr.beginTransaction();
    
    /****After add , replace fragments 
      (some of the fragments are add to backstack , some are not)***/
    
    //HERE, How can I get the latest added fragment from backstack ??
    
  • Leem.fin
    Leem.fin over 12 years
    But how can I get the last fragment in backstack?? The popBackStackEntryAt() only returns an BackStackEntry instance, NOT fragment
  • Blackbelt
    Blackbelt over 12 years
    yes you are right, but every BackStackEntry holds and id which you can retrive with getId(). you can use this Id in order to retrieve the fragment
  • An-droid
    An-droid about 11 years
    To get the last fragment : getBackStackEntryCount() - 1
  • Braj
    Braj almost 11 years
    this is helpful. Irrespective of getting which fragment is added to stack recently, we can get any fragment in stack by name
  • Saqib
    Saqib almost 11 years
    in order to find fragment by tag it must be added/replaced with same tag. FragmentTransaction.add(int containerViewId, Fragment fragment, String tag) or FragmentTransaction.replace(int containerViewId, Fragment fragment, String tag) doc
  • Admin
    Admin over 10 years
    But then in order to get that fragment by id (getId()) you have to maintain your own stacks independent of the Android back stack).
  • Justin
    Justin about 10 years
    This answer is wrong, I'm seeing the backstack entries have an id of 0, so can't retrieve the fragment by id.
  • Justin
    Justin about 10 years
    The problem with this is if you have a fragment in the back stack twice, you can't retrieve a specific fragment when all you have is the index or backstackentry entity.
  • Blackbelt
    Blackbelt about 10 years
    @Justin the documentations says Return the unique identifier for the entry. This is the only representation of the entry that will persist across activity instances.
  • Arne Evertsson
    Arne Evertsson almost 10 years
    This answer works well in my project since I add every fragment except the root fragment to the back stack. But I guess this answer will not work if the latest added fragment wasn't added to the backstack.
  • Arne Evertsson
    Arne Evertsson almost 10 years
    Like @Saqib says, will it really work to retrieve the fragment from the back entry tag name? They are not the same, or are they?
  • Kenny Worden
    Kenny Worden over 9 years
    What's the point of calling it a stack if I can't access the fragment via a pop method?
  • artkoenig
    artkoenig over 9 years
  • peterk
    peterk almost 9 years
    It seems if I use the name from the BackStackEntry to findFragmentByTag() using the name returned by the entry it returns NULL which seems like a bug - if I get the fragment list from the fragment manager the fragment is in the list this is on 4.4.2 really annoying.
  • peterk
    peterk almost 9 years
    of course if the list is the stack then one could use the last entry but it is not documented in this way.
  • maciekjanusz
    maciekjanusz about 8 years
    This is old, but for anybody that wanders here: back stack does not hold fragments, but fragment transactions, that's why this answer is wrong
  • Deepak Goel
    Deepak Goel almost 8 years
    @TeodorKolev Have you used the same tag during add or replace. FragmentTransaction.add(int containerViewId, Fragment fragment, String tag) or FragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
  • ToolmakerSteve
    ToolmakerSteve almost 8 years
    1) I think you mean getBackStackEntryAt rather than popBackStackEntryAt? 2) Despite the negative comments, getId() is useful for most cases, where there is only a single fragment of each type. Then use fragmentManager.findFragmentById( id ). Limitation is if a fragment type is inflated multiple times, only one of them can be found. In that case, use tags (names): stackoverflow.com/a/28046389/199364
  • Blackbelt
    Blackbelt almost 8 years
    @ToolmakerSteve, the answer is 4 years old
  • ToolmakerSteve
    ToolmakerSteve almost 8 years
    Not reliable. Three reasons: 1) This is a list of all fragments the fragment manager knows about, not just those on the stack. 2) There is no guarantee that the fragment manager will keep adding new ones at the end of the list. Sure, it will do so in simple tests, but what if a fragment is removed, leaving a null, and then under some circumstances the fragment manager decides to reuse that empty slot? Not saying it does, but there is no guarantee it never will, under any circumstances. 3) If you or some future programmer starts using attach/detach to manage fragments, this won't match stack.
  • Shirane85
    Shirane85 over 7 years
    This will only work if you give all the fragment the same tag, which is not a good idea if you want to find a specific fragment later.
  • eC Droid
    eC Droid almost 7 years
    Yes for above to work you have to use same String value for fragment tag and backstack name otherwise it won't work. So this can be taken as a work around but not a proper solution.
  • htafoya
    htafoya almost 7 years
    I don't know why but findFragmentByTag is returning null, even when the debugger clearly shows that the tag is ok.
  • Shirane85
    Shirane85 over 6 years
    Thanks. The most elegant answer. Added it here for Kotlin lovers stackoverflow.com/a/47336504/1761406
  • Muhammad Ali
    Muhammad Ali over 5 years
    Hi, thanks for your solution but it is not beautiful and easy
  • Westy92
    Westy92 almost 5 years
    You may need to use .lastOrNull() in case fragments is empty.
  • CoolMind
    CoolMind over 4 years
    I doubt it is a working solutuin. getFragments() returns a shortened collection of fragments. Maybe the last one is visible, but not many others.
  • davidbilla
    davidbilla over 4 years
    you got 50 now :)