How do I get the currently displayed fragment?
Solution 1
When you add the fragment in your transaction you should use a tag.
fragTrans.replace(android.R.id.content, myFragment, "MY_FRAGMENT");
...and later if you want to check if the fragment is visible:
MyFragment myFragment = (MyFragment)getSupportFragmentManager().findFragmentByTag("MY_FRAGMENT");
if (myFragment != null && myFragment.isVisible()) {
// add your code here
}
See also http://developer.android.com/reference/android/app/Fragment.html
Solution 2
I know it's an old post, but was having trouble with it previously too. Found a solution which was to do this in the onBackStackChanged()
listening function
@Override
public void onBackPressed() {
super.onBackPressed();
Fragment f = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
if(f instanceof CustomFragmentClass)
// do something with f
((CustomFragmentClass) f).doSomething();
}
This worked for me as I didn't want to iterate through every fragment I have to find one that is visible.
Solution 3
Here is my solution which I find handy for low fragment scenarios
public Fragment getVisibleFragment(){
FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
List<Fragment> fragments = fragmentManager.getFragments();
if(fragments != null){
for(Fragment fragment : fragments){
if(fragment != null && fragment.isVisible())
return fragment;
}
}
return null;
}
Solution 4
Every time when you show fragment you must put it tag into backstack:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK);
ft.add(R.id.primaryLayout, fragment, tag);
ft.addToBackStack(tag);
ft.commit();
And then when you need to get current fragment you may use this method:
public BaseFragment getActiveFragment() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
return null;
}
String tag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
return (BaseFragment) getSupportFragmentManager().findFragmentByTag(tag);
}
Solution 5
Kotlin way;
val currentFragment = supportFragmentManager.fragments.last()
Comments
-
Leem.fin almost 2 years
I am playing with fragments in Android.
I know I can change a fragment by using the following code:
FragmentManager fragMgr = getSupportFragmentManager(); FragmentTransaction fragTrans = fragMgr.beginTransaction(); MyFragment myFragment = new MyFragment(); //my custom fragment fragTrans.replace(android.R.id.content, myFragment); fragTrans.addToBackStack(null); fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); fragTrans.commit();
My question is, in a Java file, how can I get the currently displayed Fragment instance?
-
Leem.fin over 12 yearsMy question is how to get currently displayed fragment, which means there could be a lot of fragments, I only want to get the instance of the currently displayed one, why use (MyFragment) ?? I mean it could be any Fragment display on the screen...and I want to get the currently displayed one.
-
Thordax over 12 yearsMY_TAG_FRAGMENT is the tag of the fragment I created before using a replace, like this : fragmentTransaction.replace(R.id.FL_MyFragment, MyFragment, MY_TAG_FRAGMENT);
-
Leem.fin over 12 yearsIf I have multiple fragments, can I use one tag for all the fragments when call .replace(...) ?
-
Thordax over 12 yearsYes, no problem, use this code : fragmentTransaction.replace(R.id.FL_MyFragment, MyFragment, MY_TAG_FRAGMENT); and it may go well.
-
Leem.fin over 12 yearsOk, so if I use one tag for all fragments, once I findFragmentByTag(tag), it will returns me the currently displayed fragment, am I right?
-
Leem.fin over 12 yearsOk, but I need a way to immediately get the currently displayed Fragment instance, not iteratively check through all fragments and then decide which fragment is now displayed on the screen. I think your answer needs my code to iteratively check each of my fragments, and find out the visible one ...
-
Thordax over 12 yearsCareful because you will get a ClassCastException if you try to get the fragment by doing what i said on my first post !
-
ramdroid over 12 yearsYes, but there could be more than one fragment visible at a time. So there is nothing like the "only active fragment"....
-
Leem.fin over 12 yearsWell, I really don't get your point, I mean I need a way to immediately get the currently displayed Fragment instance, not iteratively check through all fragments and then decide which fragment is now displayed on the screen.
-
Leem.fin over 12 yearsOk, even there are several fragments displayed, I still need a way to get them... and a way which is better than iteratively check each of my fragments . I am concern on "get them" a method like getDisplayedFragment(), but not sure is there such method in Android
-
ramdroid over 12 yearsI don't know why this is a problem to you... You usually have only few fragments in an activity and it shouldn't really be a problem to check them if they are visible or not.
-
loeschg over 10 yearsI'm fairly sure this technique won't work for Fragments used with a ViewPager, as they're not added by tag. Just tossing that out there.
-
TrtG over 10 yearswouldn't that give a NPE if the fragment has never been displayed yet?
-
cprcrack over 10 yearsThis only seems to work when you call
addToBackStack(tag)
, but what if you don't wan't to add the fragment to the back stack? -
cprcrack over 10 years
fragment
can be null in certain scenarios, such as when you pop the back stack. So better useif (fragment != null && fragment.isVisible())
. -
Admin over 10 yearsThis only works if your tag happens to be the same as the back stack name, which seems like it'd be unusual.
-
kehers almost 10 yearsYou should check to be sure count > 0 so that get(count-1) doesn't throw an IndexOutofBoundsException
-
Kevin Lam almost 10 yearsWhat happens if you added 5 fragments in the same transaction?
-
ShortFuse almost 10 yearsExactly what I was looking for when dealing with onBackPressed() after screen rotation with a Navigation Drawer. Thanks for coming back to share this.
-
JacksOnF1re almost 10 yearsIf your phone is turned of isVisible will return false. Therefore this method does not indicates correct if fragment is the stack top one.
-
JacksOnF1re almost 10 yearsIt is maybe nice to say that if you call addToBackStack(null) for some Fragment where you do not need a name, the method getName() can return null and you get a NPE. @ dpk, docu says: Get the name that was supplied to FragmentTransaction.addToBackStack(String) when creating this entry. Also ,add a null check if EntryCount is 0 and you try to receive the top entry.
-
letroll over 9 yearsmethod incomplete because it's possible there are not only one fragment visible
-
Michael Peterson over 9 yearsCheck if myFragment is null or not before checking if it is visible. if (myFragment != null && myFragment.isVisible()) { ... }
-
parvus over 9 yearsStrangely enough, this was the only solution listed here that worked for me. At the same time, multiple fragments can have
isVisible() == true
,getView() != null
. Plus, in my codegetBackStackEntryCount
is always zero. Even though I don't use menu's,isMenuVisible()
is so far the only discriminant that seems to point reliably to the currently 'active' fragment. ty -
Andrew Senner about 9 yearsDoesn't findFragmentById iterate through all the fragments internally? :)
-
Răzvan Barbu almost 9 yearsin case
.getFragmentManager
reports incompatible type, as it did in my case, it is because I was using theandroid.support.app.v4.Fragment
, in which case the right method to use isgetSupportFragmentManager
-
DeltaCap019 almost 9 yearsor you can use
findFragmentByTag()
in place offindFragmentById
, if you have provided tag to fragment when adding it tofragmentManager.beginTransaction() .add(containerID, frag, fragmentTag) .addToBackStack(fragmentTag) .commit();
-
user798719 almost 9 yearsfragTrans.replace(android.R.id.content, myFragment, "MY_FRAGMENT"); is used to set a TAG. But when I find the fragment later by TAG, it's null. Driving me nuts!
-
cafebabe1991 over 8 years@tainy this wont give the fragment that was replaced but not added to the backstack .Right ? If yes, then can i get it using the tag argument ?
-
Pranav Mahajan over 8 yearsIf no fragment is visible, then fragmentManager.getFragments() will return NULL which will lead to NPE saying "Attempt to invoke interface method 'java.util.Iterator java.util.List.iterator()' on a NULL object reference". Therefore, the for loop should be surrounded by a simple check: if (fragments != null)
-
Shayan Amani over 8 yearsYou need also to put the TAG in the addToBackStack(). take a look to @Dmitry_L answer for this case.
-
monad98 over 8 yearswould you please explain more detail?
-
user2413972 about 8 yearsYeah. And as for the treatment of "Back" you have not forgotten?
-
LEHO about 8 yearsThe getFragments call won't give you the fragments the order they were added after you call popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) on it, and add more fragments.
-
Shivaraj Patil almost 8 yearsWhat if more than one fragments are visible?
-
user1324887 almost 8 years@ShivarajPatil, In case of
ActionBar
more than 1 fragment is visiable, Did you find a solution? -
Shivaraj Patil almost 8 years'@user1324887 nop but what you can do is instead of returning a single fragment inside loop, add fragments to a list like List of visible fragments and return that list & go through each of them may be. Not perfect solution & I have not tested this.
-
HungNM2 over 7 yearsif activity have more than one Fragment visible, your way is wrong. For example: ViewPager with Fragments. as I known getBackStackEntryCount() return number of Transaction, not number of fragment
-
Stumi over 7 yearsUnfortunately, this is not always true, the
getSupportFragmentManager().getFragments()
gives you back a list but that can hold null values, if the latest fragment just been popped from the backstack. Eq: If you check with your way inside theonBackStackChanged()
method and you call thepopBackStack()
somewhere , then themCurrentFragment
will benull
. -
angryITguy about 7 yearsWhy is everyone upvoting this answer ? Sure, it's a nice bit of code but doesn't answer the question to get a specific fragment by tag.. BUT Asker wants the currently displayed fragment, which means he doesn't know which fragment is displayed. Yes, there may be multiple fragments, but reading the question infers only 1 fragment is displayed on the UI.... Sorry had to downvote because it doesn't answer the question context.
-
angryITguy about 7 yearsTechnically this should be marked as answer based on the question. Asker wants currently displayed fragment, not knowing which fragment it is. Other answers keep getting fragments by tag
-
malli over 6 yearsHow can we use eventbus in this scenario??can you please share me one example.
-
Tim over 6 yearshow is that reactive? You use an observable but it will only emit once
-
Peterstev Uremgba about 6 yearsAnd it's Just an overkill. A simple enhanced forloop would do just the same, maybe even faster.
-
Ajit Kumar Dubey about 6 yearsSuppose I have 10 Fragment then I need to write multiple line of code for checking which fragment is active. is there any best way to find the which fragment is active now without checking and typecasting multiple times.
-
AndroidLover almost 6 yearsusing reactive stream for just stream api is not that smart , in fact like they said it is an overkill use the steam Java8 api if you want to treat the list as a stream and apply the filter api
-
Pritesh Vishwakarma over 5 years
MainFragment myFragment = (MainFragment)getSupportFragmentManager().findFragmentById(R.id.frame_layout); if (myFragment != null && myFragment.isVisible()) { Log.d(TAG,"myFragment is opened"); } else { Log.d(TAG,"myFragment is not opened and null"); }
@AjitKumarDubey try this , with the help of this you dont have to keep track of every fragment tag. instead, usefindFragmentById
to find fragment and cast with class name and you can have condition for checking every fragment. -
RustamG over 5 yearsYou should check
fragManager.getFragments().size()
instead ofgetBackStackEntryCount()
as they are not necessarily equal (which is my case). Otherwise you can get crash with IndexOutOfBoundsException -
Farid about 5 years@AndrewSenner, he means he didn't want to do it explicitly :)
-
ibit about 5 yearsWorks on API 26 and up only
-
Nativ about 5 years@Stumi Thanks for this information. Yep, sounds like one of many weird life cycle problems in Android.
-
HendraWD about 5 years@ibit what do you mean with works on API 26 and up only? I tried on emulator API 19 working fine.
-
ibit about 5 years@HendraWD you are correct! I was referring to the function in the frameworks
getFragments()
function, which is API 26 and up. -
TheRealChx101 almost 5 yearsThis will not work well if you want to have a value returned
-
David García Bodego over 4 yearsWelcome to SO! When you post an answer, even if it is right, try to comment it a little bit. In this case, with another 41 answer, you should exposed Pros and Cons of your P.O.V.
-
Saddan over 4 yearsThank you david , I appreciate your suggestion
-
Jetwiz over 4 yearstake care. If before you dont have any fragment stack, it can cause empty exception!
-
Blundell over 4 yearsso so close! :-)
-
IgorGanapolsky about 4 yearsThis doesn't compile
-
IgorGanapolsky about 4 yearsWe use Jetpack Navigation library
-
Cory Roy about 4 yearsIt would only compile if you had properly setup AndroidX navigation and somehow called your navHost
your_navhost
. -
coolcool1994 about 4 yearsThis doesn't work? java.lang.ClassCastException: androidx.navigation.fragment.NavHostFragment cannot be cast to Fragment
-
coolcool1994 about 4 yearsCorrect way is: supportFragmentManager.fragments.last()?.getChildFragmentManager()?.getFragments()?.get(0)
-
Kishan Solanki almost 4 yearsTry to navigate between fragments and press back, app will be crashed!
-
Michael Abyzov over 3 yearsI'm not sure, but maybe to get currently displayed fragment
firstOrNull( )
instead oflastOrNull( )
should be used? -
RodParedes over 2 yearsThis only works when you use fragmentManager.replace().commit() and not when is used fragmentmanager.add().hide().show().commit() right?
-
Torima about 2 yearsThis returns destination, not a fragment. If you need fragment you can use:
supportFragmentManager.findFragmentById(R.id.your_nav_graph_container).childFragmentManager.primaryNavigationFragment
-
George Ampartzidis about 2 yearsThis is the only answer I could use in my case! Thank you!