Can fragment be created with only one instance - android

I was just wondering, can fragment creation only have one instance or singleton?
I went through Google iosched project too. They simply create
Fragment a = new Fragment();
Whenever they want...
Suppose eg:
public static FragmentManager instance;
public static FragmentManager getInstance() {
if (instance == null) {
instance = new FragmentManager();
}
return instance;
}
public TestFragment getTestFragment() {
if (testFragment == null) {
testFragment = new TestFragment ();
}
return testFragment
}
}
Can I use everywhere
FragmentManager.getInstance().getTestFragment() for transaction?
eg:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, FragmentManager.getInstance().getTestFragment())
.commit();
Or OS automatically destroy the reference or some issues related to it?

When you use getSupportFragmentManager().beginTransaction().replace you can add a third parameter as a string that you can use as a tag, so in case you want to recover a previous fragment you can use getSupportFragmentManager().findFragmentByTag(String) so you won't have to create a new fragment.
So it would be like this
Check if the fragment exists using findFragmentByTag(String) if it not exists, create a new fragment and call getSupportFragmentManager().beginTransaction() .replace(R.id.content_frame,myFragment,myTag).commit(); where myTag is the String you'll use in your findFragmentByTag. This way you won't create more than one fragment of every type.
I hope it makes some sense :)
For more information check this and this

No such limitation. Though, two fragment objects must not have same tag or id.
Also, its good to re-attach an existing fragment, rather that creating a new one.
MyFragment f = (MyFragment) getFragmentManager().findFragmenByTag("my_fragment");
if(f == null){
f = Fragment.instantiate(context, MyFragment.class.getName());
}
if(!f.isAdded()){
//--do a fragment transaction to add fragment to activity, WITH UNIQUE TAG--
//--Optionally, add this transaction to back-stack as well--
}

If you are trying to make sure that you will not add or replace one or more of your fragments with the same "type" twice or more, then you can use the FragmentManager.BackStackEntry to know which of your fragments is currently on the top of the stack.
String TAG_FIRST_FRAGMENT = "com.example.name.FIRST.tag";
String TAG_SECOND_FRAGMENT = "com.example.name.SECOND.tag";
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() == 0 ||
!fragmentManager.getBackStackEntryAt(
fragmentManager.getBackStackEntryCount() - 1)
.getName().equals(TAG_SECOND_FRAGMENT)) {
//Now it's safe to add the secondFragment instance
FragmentTransaction transaction = fragmentManager.beginTransaction();
//Hide the first fragment if you're sure this is the one on top of the stack
transaction.hide(getSupportFragmentManager().findFragmentByTag(TAG_FIRST_FRAGMENT));
SecondFragment secondFragment = new SecondFragment();
transaction.add(R.id.content_frame, secondFragment, TAG_SECOND_FRAGMENT);
//Add it to back stack so that you can press back once to return to the FirstFragment, and
//to make sure not to add it more than once.
transaction.addToBackStack(TAG_SECOND_FRAGMENT);
transaction.commit();
}

Related

Common way to switch fragments without loosing state

I am pretty new to android development so I am curious how to work properly with Fragments.
My application contains a BottomNavigationActivity which switches between 3 fragments with this code:
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_montage_order_detail, fragment).commit();
I am storing the Fragments in a List<Fragment> to avoid loosing the current state. But everytime I replace the fragment with another the method onDestroy() is called.
I know, I know I could add and remove the fragment in the fragmentmanager instead of replacing it. I googled alot and most of the tutorials tell me to replace the fragment.
Whats the common way to keep a fragments state without recreating it on every call?
Find the solution
It will not recreate fragment anytime
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().add(R.id.content_montage_order_detail, fragment).commit();
Use fragment TAG at time of creation of fragment then when you want to get it again use findFragmentByTag. if fragment already created then old one will be find by fragment manager.
Fragment previousFragment = fragmentManager.findFragmentByTag("TAG");
I suggest you use show,not forreplace
protected void addFragmentStack(Fragment fragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (this.mContent != fragment) {
if (fragment.isAdded()) {
ft.hide(this.mContent).show(fragment);
} else {
ft.hide(this.mContent).add(getFragmentViewId(), fragment);
}
this.mContent = fragment;
}
ft.commit();
}
Try using switchFragment to switch fragment, it will show fragment if it is already added.
Use fragmentTransaction.show method to re-use existing fragment i.e. saved instance.
public void switchFragment (Fragment oldFragment, Fragment newFragment, int frameId) {
boolean addFragment = true;
FragmentManager fragmentManager = getFragmentManager ();
String tag = newFragment.getArguments ().getString (BaseFragment.TAG);
Fragment fragment = fragmentManager.findFragmentByTag (tag);
// Check if fragment is already added
if (fragment != null && fragment.isAdded ()) {
addFragment = false;
}
// Hide previous fragment
String oldFragmentTag = oldFragment.getArguments ().getString (BaseFragment.TAG);
if (!tag.equals (oldFragmentTag)) {
FragmentTransaction hideTransaction = fragmentManager.beginTransaction ();
Fragment fragment1 = fragmentManager.findFragmentByTag (oldFragmentTag);
hideTransaction.hide (fragment1);
hideTransaction.commit ();
}
// Add new fragment and show it
FragmentTransaction addTransaction = fragmentManager.beginTransaction ();
if (addFragment) {
addTransaction.add (frameId, newFragment, tag);
addTransaction.addToBackStack (tag);
}
else {
newFragment = fragmentManager.findFragmentByTag (tag);
}
addTransaction.show (newFragment);
addTransaction.commit ();
}
Ya, you can also manage the state by managing the backstack.

How to reuse existing fragment from FragmentManager instead of re-creating them again?

I am using NavigationDrawer in my application and each menu item in drawer is a fragment.Whenever user chooses a menu item I replace the current fragment in the main container with the requested one but it recreates the fragment every-time, so i updated my code to reuse the existing fragments instead of creating them again and again as content of fragments remain same. My updated code to show fragment is :
public void showTabFragment() {
TabFragment Tf = (TabFragment) mFragmentManager.findFragmentByTag(Constants.TAB_FRAGMENT);
mFragmentTransaction = mFragmentManager.beginTransaction();
if (Tf != null) {
mFragmentTransaction.replace(R.id.containerView, Tf, Constants.TAB_FRAGMENT);
} else {
mFragmentTransaction.replace(R.id.containerView, new TabFragment(), Constants.TAB_FRAGMENT);
}
mFragmentTransaction.commit();
}
In above code I am trying to get fragments by Tag but it always returns null and executes the else case(new fragment).Could someone please guide me what am I doing wrong in my code?
I guess the code you've shown is for one of your menu fragment? If that's the case, what is probably happening is every time you open a menu item, the container is replaced with the new fragment(say, Fragment B) with its new tag(say, TAG 'B'). So, when you try to open the previous fragment(say, Fragment A) using it's tag(TAG 'A'), it won't be there, because that's what you replaced.
One possible solution is to hold references to the fragment as they are created, in, say a hashmap, and reuse them instead.
private HashMap<String, Fragment> menuFragments = new HashMap<>();
public void showMenu(String fragmentID)
{
MenuFragment fragment = menuFragments.get(fragmentID);
if(fragment == null)
{
fragment = new MenuFragment(); //Create the respective menu fragment based on the ID.
menuFragments.put(fragmentID, fragment);
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.containerView, fragment, fragmentID);
transaction.commit();
}

Prevent the same Fragment to be added multiple times in popBackStack

My activity is composed of 3 nested Fragments. There is my MainFragment that is displayed by default, ProductFragment that can be called from it, then DetailFragment can be called from ProductFragment.
I can go back and forth between my ProductFragment and DetailFragment. By doing so, the popStackBack method is accumulating similar fragments. Then, if I click on the back button, It will go back through all the Fragments as many time I called them.
What is the proper way to avoid the same Fragment to be kept in the back stack ?
EDIT :
I firstly call my main fragment :
if (savedInstanceState == null) {
getFragmentManager()
.beginTransaction()
.add(R.id.container, new SearchFragment(), "SEARCH_TAG")
.commit();
}
Here is the code that calls the fragments from the activity :
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.animator.enter_from_bottom, R.animator.exit_to_top, R.animator.enter_from_bottom, R.animator.exit_to_top);
ft.replace(R.id.container, new FactFragment(), "FACT_TAG");
ft.addToBackStack("FACT_TAG");
ft.commit();
Then, on back click :
#Override
public void onBackPressed() {
getFragmentManager().popBackStack();
}
I tried to get the tag of my current fragment and execute some specific code related to it but it doesn't work well. I also tried to addToBackStack() only when current Fragment wasn't already added to the backStack but it messed up my fragment view.
Use fragment's method isAdded() to evaluate the insertion. For example:
if(!frag.isAdded()){
//do fragment transaction and add frag
}
Here is my solution. Maybe dirty but it works. I implemented a method that returns the tag of the fragment that is displayed before clicking the on back button :
public String getActiveFragment() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
return null;
}
String tag = getFragmentManager()
.getBackStackEntryAt(getFragmentManager()
.getBackStackEntryCount() - 1)
.getName();
return tag;
}
Then, on my onBackPressed() method :
// Get current Fragment tag
String currentFrag = getActiveFragment();
if(currentFrag.equals("PRODUCT_TAG")) {
// New transaction to first Fragment
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.animator.enter_from_right, R.animator.exit_to_left, R.animator.enter_from_right, R.animator.exit_to_left);
ft.replace(R.id.container, new SearchFragment(), "MAIN_TAG");
ft.commit();
} else {
// Go to Fragment-1
getFragmentManager().popBackStack();
}
Here is my handy and simple solution to check for duplicate insertion through fragment manager
at first, I check if it is first time intention for adding fragment and then I check if the fragment is presented using fragment manager
Fragment fragment = getSupportFragmentManager().findFragmentByTag("firstFragment");
if (fragment == null) {
getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new FirstFragment(), "firstFragment")
.addToBackStack(null)
.commit();
}else if(!fragment.isAdded()){
getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new FirstFragment(), "firstFragment")
.addToBackStack(null)
.commit();
}
Here is my solution:
Fragment curFragment = fragmentManager.findFragmentById(R.id.frameLayout);
if(curFragment != null
&& curFragment.getClass().equals(fragment.getClass())) return;
// add the fragment to BackStack here
Xamarin.Android (C#) version:
var curFragment = fragmentManager.FindFragmentById(Resource.Id.frameLayout);
if (curFragment != null
&& curFragment.GetType().Name == fragment.GetType().Name) return;
// add the fragment to BackStack here

GetFragmentManager.findFragmentByTag() returns null

getFragmentManager().beginTransaction()
.replace(R.id.graph_fragment_holder, new GraphFragment(), "GRAPH_FRAGMENT")
.commit();
getFragmentManager().beginTransaction()
.replace(R.id.list_fragment_holder, new ListFragment(), "LIST_FRAGMENT")
.commit();
//getFragmentManager().executePendingTransactions();
GraphFragment graphFragment = (GraphFragment) getFragmentManager().findFragmentByTag("GRAPH_FRAGMENT");
graphFragment.setData(data);
ListFragment listFragment = (ListFragment) getFragmentManager().findFragmentByTag("LIST_FRAGMENT");
listFragment.setData(data);
I've supplied a tag so I'm not sure why findFragmentByTag() returns null.
What I've tried from reading other questions:
this.setRetainInstance(true) in the oncreate of both fragments.
Both fragment constructors are empty public fragmentName(){}.
tried executePendingTransactions after adding the fragments.
tried add instead of replace on the fragments (edited)
I was confused about this for a long time. First, you need to save the fragment you are replacing by pushing it onto the back stack. The tag you supply is put on the fragment you are adding, not the one you are pushing onto the back stack. Later, when you do push it onto the back stack, that tag goes with it. Here's code with objects broken out to make it easier to trace. You must call 'addToBackStack' before 'commit'.
GraphFragment grFrag = new GraphFragment();
FragmentTransaction tr = getSupportFragmentManager().beginTransaction();
tr.replace(R.id.fragment_container, grFrag, "GRAPH_FRAGMENT");
// grFrag is about to become the current fragment, with the tag "GRAPH_FRAGMENT"
tr.addToBackStack(null);
// 'addToBackStack' also takes a string, which can be null, but this is not the tag
tr.commit();
// any previous fragment has now been pushed to the back stack, with it's tag
ListFragment liFrag = new ListFragment();
FragmentTransaction tr = getSupportFragmentManager().beginTransaction();
tr.replace(R.id.fragment_container, liFrag, "LIST_FRAGMENT");
// liFrag is is about to become the current fragment, with the tag "LIST_FRAGMENT"
tr.addToBackStack(null);
tr.commit();
// 'grFrag' has now been pushed to the back stack, with it's tag being "GRAPH_FRAGMENT"
Call getFragmentManager().executePendingTransactions() after fragment transaction.
getFragmentManager()
.beginTransaction()
.replace(R.id.container, new ExampleFragment(), "YOUR TAG HERE");
.commit();
//after transaction you must call the executePendingTransaction
getFragmentManager().executePendingTransactions();
//now you can get fragment which is added with tag
ExampleFragment exampleFragment = getFragmentManager().findFragmentByTag("YOUR TAG HERE");
I was having the same problem of findFragmentByTag() always returning null.
Eventually I tracked it down, I was overriding onSaveInstanceState() in my Activity but not calling super. As soon as I fixed that findFragmentByTag() returned the Fragment as expected.
You can use
fragmentTransaction.addToBackStack(yourFragmentTag);
After that you can reuse it with
getSupportFragmentManager().findFragmentByTag(yourFragmentTag);
Answered here, just need to call getSupportFragmentManager().executePendingTransactions(); after your findByTag or findById
In my case I had to create a class level FragmentManager object and then use it instead of using getSupportFragmentManager() directly.
public class Main extends BaseActivity {
FragmentManager fragmentManager;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragmain);
fragmentManager = getSupportFragmentManager();
initFrag1();
}
private void initFrag1() {
String name = Frag1.class.getSimpleName();
if (fragmentManager.findFragmentByTag(name) == null) {
fragmentManager.beginTransaction()
.add(R.id.frag_container, new Frag1(), name)
.addToBackStack(name)
.commit();
}
}
}

How do I get the currently displayed fragment?

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?
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
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.
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;
}
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);
}
Kotlin way;
val currentFragment = supportFragmentManager.fragments.last()
What I am using to find current displaying fragment is in below code. It is simple and it works for me by now. It runs in the activity which holds the fragments
FragmentManager fragManager = this.getSupportFragmentManager();
int count = this.getSupportFragmentManager().getBackStackEntryCount();
Fragment frag = fragManager.getFragments().get(count>0?count-1:count);
The reactive way:
Observable.from(getSupportFragmentManager().getFragments())
.filter(fragment -> fragment.isVisible())
.subscribe(fragment1 -> {
// Do something with it
}, throwable1 -> {
//
});
My method is based on try / catch like this :
MyFragment viewer = null;
if(getFragmentManager().findFragmentByTag(MY_TAG_FRAGMENT) instanceOf MyFragment){
viewer = (MyFragment) getFragmentManager().findFragmentByTag(MY_TAG_FRAGMENT);
}
But there may be a better way ...
If you are using the AndroidX Navigation:
val currentFragment = findNavController(R.id.your_navhost)?.currentDestination
For more info on this navigation component:
https://developer.android.com/guide/navigation/navigation-getting-started
Well, this question got lots of views and attention but still did not contained
the easiest solution from my end - to use getFragments().
List fragments = getSupportFragmentManager().getFragments();
mCurrentFragment = fragments.get(fragments.size() - 1);
You can query which fragment is loaded into your Activities content frame, and retrieve the fragment class, or fragment 'simple name' (as a string).
public String getCurrentFragment(){
return activity.getSupportFragmentManager().findFragmentById(R.id.content_frame).getClass().getSimpleName();
}
Usage:
Log.d(TAG, getCurrentFragment());
Outputs:
D/MainActivity: FragOne
If get here and you are using Kotlin:
var fragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
R.id.fragment_container is the id where the fragment is presenting on their activity
Or if you want a nicer solution:
supportFragmentManager.findFragmentById(R.id.content_main)?.let {
// the fragment exists
if (it is FooFragment) {
// The presented fragment is FooFragment type
}
}
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!
1)
ft.replace(R.id.content_frame, fragment, **tag**).commit();
2)
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment currentFragment = fragmentManager.findFragmentById(R.id.content_frame);
3)
if (currentFragment.getTag().equals(**"Fragment_Main"**))
{
//Do something
}
else
if (currentFragment.getTag().equals(**"Fragment_DM"**))
{
//Do something
}
There's a method called findFragmentById() in SupportFragmentManager. I use it in the activity container like :
public Fragment currentFragment(){
return getSupportFragmentManager().findFragmentById(R.id.activity_newsfeed_frame);
}
That's how to get your current Fragment. If you have custom Fragment and need to check what Fragment it is, I normally use instanceof :
if (currentFragment() instanceof MyFrag){
// Do something here
}
This should work -
val visibleFragment = supportFragmentManager.fragments.findLast { fgm -> fgm.isVisible }
Timber.d("backStackIterator: visibleFragment: $visibleFragment")
Inspired by Tainy's answer, here is my two cents. Little modified from most other implementations.
private Fragment getCurrentFragment() {
FragmentManager fragmentManager = myActivity.getSupportFragmentManager();
int stackCount = fragmentManager.getBackStackEntryCount();
if( fragmentManager.getFragments() != null ) return fragmentManager.getFragments().get( stackCount > 0 ? stackCount-1 : stackCount );
else return null;
}
Replace "myActivity" with "this" if it is your current activity or use reference to your activity.
This is simple way to get current fragment..
getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override public void onBackStackChanged() {
currentFragment = fragmentManager.findFragmentById(R.id.content);
if (currentFragment != null && (currentFragment instanceof LoginScreenFragment)) {
logout.setVisibility(View.GONE);
} else {
logout.setVisibility(View.VISIBLE);
}
}
});
Checkout this solution. It worked for me to get the current Fragment.
if(getSupportFragmentManager().getBackStackEntryCount() > 0){
android.support.v4.app.Fragment f =
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if(f instanceof ProfileFragment){
Log.d(TAG, "Profile Fragment");
}else if(f instanceof SavedLocationsFragment){
Log.d(TAG, "SavedLocations Fragment");
}else if(f instanceof AddLocationFragment){
Log.d(TAG, "Add Locations Fragment");
}
it's so simple, not that much code you need to write
yourFragment.isAdded()
or
yourFragment.isVisible();
I prefer isAdded(),both of them return boolean value use it in if condition and must initialize your fragment in onCreate() otherwise you will get null point exception.
None of the above 30 answers fully worked for me. But here is the answer that worked:
Using Kotlin, when using Navigation Component:
fun currentVisibleFragment(): Fragment? {
return supportFragmentManager.fragments.first()?.getChildFragmentManager()?.getFragments()?.get(0)
}
Sev's answer works for when you hit the back button or otherwise change the backstack.
I did something slightly different, though. I have a backstack change listener setup on a base Fragment and its derived fragments and this code is in the listener:
Fragment f = getActivity().getSupportFragmentManager().findFragmentById(R.id.container);
if (f.getClass().equals(getClass())) {
// On back button, or popBackStack(),
// the fragment that's becoming visible executes here,
// but not the one being popped, or others on the back stack
// So, for my case, I can change action bar bg color per fragment
}
Easy way to do that :
Fragment fr=getSupportFragmentManager().findFragmentById(R.id.fragment_container);
String fragmentName = fr.getClass().getSimpleName();
I had to do this very recently
public Fragment getCurrentFragment() {
return fragmentManager.findFragmentById(R.id.container);
}
and finaly i got last fragment on this container.
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");
}
If you are getting the current instance of Fragment from the parent activity you can just
findFragmentByID(R.id.container);
This actually get's the current instance of fragment that's populated on the view. I had the same issue. I had to load the same fragment twice keeping one on backstack.
The following method doesn't work. It just gets a Fragment that has the tag. Don't waste your time on this method. I am sure it has it's uses but to get the most recent version of the same Fragment is not one of them.
findFragmentByTag()
Kotlin safer way than exposed here
supportFragmentManager.fragments.lastOrNull()?.let { currentFragment ->
//Do something here
}
This is work for me. I hope this will hepl someone.
FragmentManager fragmentManager = this.getSupportFragmentManager();
String tag = fragmentManager
.getBackStackEntryAt(
fragmentManager
.getBackStackEntryCount() - 1)
.getName();
Log.d("This is your Top Fragment name: ", ""+tag);
I found findFragmentByTag isn't that convenient. If you have String currentFragmentTag in your Activity or parent Fragment, you need to save it in onSaveInstanceState and restore it in onCreate. Even if you do so, when the Activity recreated, onAttachFragment will called before onCreate, so you can't use currentFragmentTag in onAttachFragment(eg. update some views based on currentFragmentTag), because it's might not yet restored.
I use the following code:
Fragment getCurrentFragment() {
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if(fragments.isEmpty()) {
return null;
}
return fragments.get(fragments.size()-1);
}
The document of FragmentManager state that
The order of the fragments in the list is the order in which they were added or attached.
When you need to do stuff based on current fragment type, just use getCurrentFragment() instance of MyFragment instead of currentFragmentTag.equals("my_fragment_tag").
Note that getCurrentFragment() in onAttachFragment will not get the attaching Fragment, but the previous attached one.
getSupportFragmentManager().findFragmentById(R.id.content_frame).getClass().getSimpleName();
Well, I guess this is the most straight forward answer to this question.
I hope this helps.

Categories

Resources