I am playing with fragments in Android.
I know I can change a fragment by using the following code:
FragmentManager fragMgr = getSupportFragmentManag
final FragmentManager fm=this.getSupportFragmentManager();
final Fragment fragment=fm.findFragmentByTag("MY_FRAGMENT");
if(fragment != null && fragment.isVisible()){
Log.i("TAG","my fragment is visible");
}
else{
Log.i("TAG","my fragment is not visible");
}
Here is a Kotlin solution:
if ( this.getSupportFragmentManager().getBackStackEntryCount()>0 ) {
var fgmt = this.getSupportFragmentManager().fragments[this.getSupportFragmentManager().getBackStackEntryCount()-1]
if( fgmt is FgmtClassName ) {
(fgmt as FgmtClassName).doSth()
}
}
Simplified way:
with ( this.getSupportFragmentManager() ) {
if ( getBackStackEntryCount()>0 ) {
var fgmt = fragments[getBackStackEntryCount()-1]
if ( fgmt is FgmtClassName ) {
(fgmt as FgmtClassName).doSth()
}
}
}
You can do it very easily also with a URL in logcat which will redirect you to the source code of current fragment source code. First, you need to add an OnBackStackChangedListener in host activity like -
activity.getChildFragmentManager().addOnBackStackChangedListener(backStackListener);
And the OnBackStackChangedListener implementation is -
public FragmentManager.OnBackStackChangedListener backStackListener = () -> {
String simpleName = "";
String stackName = getStackTopName().trim();
if (Validator.isValid(stackName) && stackName.length() > 0) {
simpleName = stackName.substring(Objects.requireNonNull(stackName).lastIndexOf('.') + 1).trim();
List<Fragment >
fragmentList = getChildFragmentManager().getFragments();
Fragment myCurrentFragment;
for (int i = 0; i < fragmentList.size(); i++) {
myCurrentFragment= fragmentList.get(i);
if (myCurrentFragment.getClass().getSimpleName().equals(simpleName)) {
//Now you get the current displaying fragment assigned in myCurrentFragment.
break;
}
myFragment = null;
}
}
//The code below is for the source code redirectable logcat which would be optional for you.
StackTraceElement stackTraceElement = new StackTraceElement(simpleName, "", simpleName + ".java", 50);
String fileName = stackTraceElement.getFileName();
if (fileName == null) fileName = "";
final String info = "Current Fragment is:" + "(" + fileName + ":" +
stackTraceElement.getLineNumber() + ")";
Log.d("now", info + "\n\n");
};
And the getStackTopName() method is -
public String getStackTopName() {
FragmentManager.BackStackEntry backEntry = null;
FragmentManager fragmentManager = getChildFragmentManager();
if (fragmentManager != null) {
if (getChildFragmentManager().getBackStackEntryCount() > 0)
backEntry = getChildFragmentManager().getBackStackEntryAt(
getChildFragmentManager().getBackStackEntryCount() - 1
);
}
return backEntry != null ? backEntry.getName() : null;
}
It's a bit late, But for anyone who is interested : If you know the index of the your desired fragment in FragmentManager just get a reference to it and check for isMenuVisible() function! here :
getSupportFragmentManager().getFragments().get(0).isMenuVisible()
If true
Its visible to user and so on!
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. Hope it helps someone else too.
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);
}