Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getFragments method returns only 1 fragment when using replace transactions, used to return all

Tags:

As of SDK 26.0.0-beta1 and above, making use of the getFragments https://developer.android.com/reference/android/support/v4/app/FragmentManager.html#getFragments() method returns a list with only 1 fragment and the size of the list is also always 1 (so this excludes any possible null entries that might have been misleading me), when using replace method for fragment navigation.

Keep in mind I am using getSupportFragmentManager, not getFragmentManager

Prior to this SDK version all fragment transactions done with replace would be listed in the getFragments method. This means that if I replaced 10 fragments then the getFragments would return a list containing all of those 10 fragments.

However, from SDK 26.0.0-beta1 - specifically - and above (26.0.0-alpha1 and below does not have this problem) the method always returns a list of size 1 containing only the last fragment that was replaced.

To circumvent this problem I started using add and hiding whichever was the previously visible fragment, and so far this worked for what I wanted, which was to check which is the first fragment in the getFragments list whenever I needed as well as seeing if a certain instance of a fragment is already in that list.

Now a new problem arises when I try to use shared elements transitions, which only works with replace (as far as my google fu allowed me to find) meaning that if I want to use shared elements transitions I have to return to using replace fragments instead of add, but I will be back to the initial problem again.

So now I am stuck in this predicament and hoping anyone has a solution for this:

  • Is there any way to fix this?
  • Is the getFragments suppose to only return 1 fragment when we only use the replace method or is this behavior an undocumented bug that is yet to be fixed?
  • Is it possible to make shared element transitions between fragments without using replace?
like image 625
user18715 Avatar asked Oct 19 '17 10:10

user18715


People also ask

Does popBackStack destroy fragment?

FragmentManager popBackStack doesn't remove fragment.

How do I know if a fragment is already added?

You can use findFragmentByTag() or findFragmentById() functions to get a fragment. If mentioned methods are returning null then that fragment does not exist.

What transactions are available in the fragment manager?

At runtime, a FragmentManager can add, remove, replace, and perform other actions with fragments in response to user interaction. Each set of fragment changes that you commit is called a transaction, and you can specify what to do inside the transaction using the APIs provided by the FragmentTransaction class.

How do I detach a fragment?

To detach an added Fragment from an Activity, you use: getFragmentManager(). beginTransaction(). detach(mFragment). commit().


1 Answers

I know this is an old post and you've probably solved it by now, but it's the first thing I found whilst Googling the same problem so hopefully this helps someone (and probably myself when I search for the same problem in a few months' time).

If you call fragmentManager.getBackStackEntryCount() you should get a count of all your fragments on the backstack. Assuming you assigned your fragments a tag when you added/replaced them and then added them to the backstack you can then get the tag of a fragment on the backstack and use fragmentManager.findFragmentByTag() to get its instance.

To set a tag during fragment add/replace:

transaction.replace(R.id.fragment_container, newFragment, fragmentName)
transaction.add(R.id.fragment_container, newFragment, fragmentName)

And to add it to the backstack:

transaction.addToBackStack(fragmentName);

And then to loop through your backstack to find a particular fragment:

final FragmentManager fragmentManager = getSupportFragmentManager();
for (int i = fragmentManager.getBackStackEntryCount() - 1; i >= 0; i--)
{
    Fragment fragment = fragmentManager.findFragmentByTag(fragmentManager.getBackStackEntryAt(i).getName());
    // ...
}

I'm iterating through the fragments in reverse, so the last fragment I added will be returned first.

like image 185
akiller Avatar answered Oct 12 '22 23:10

akiller