Having searched regarding this issue beforehand, I can find many discussions regarding dynamically adding and removing selected Fragment
s from a ViewPager
. What I'm actually concerned about here however is how I can programmatically remove an entire ViewPager
'cleanly' from its containing ViewGroup
, when that ViewPager
has been used to display Fragment
s via a FragmentPagerAdapter
, and ensure that the contained Fragment
s are destroyed properly.
To expand on the question a bit more, I have a landscape two-pane layout where a selection is made from a list within a Fragment
on the left-hand-side, and chosen content is then placed on the right within a FrameLayout
. The key thing is that the content may or may not be paginated. Therefore, the content must either be displayed in a ViewPager
format, or if it is not paginated then it shall be represented by a single Fragment
directly.
To show a single Fragment
, I simply perform a FragmentTransaction
as you normally would in order to place the Fragment
into the FrameLayout
container. If on the other hand it's paginated content to be shown, then instead I create a ViewPager
and add it as a child of the FrameLayout
.
When I need to change the content, then if the previous content was a stand-alone Fragment
then I can simply remove it via FragmentTransaction
.remove()
. When I do this, the Fragment
goes through the onPause()
... onDestroy()
cycle as expected. If the previous content was a ViewPager
then I remove it from the FrameLayout
using .removeAllViews()
. Here I come to the problem: I don't see any of the onPause()
... onDestroy()
methods being called in any of the Fragment
s that were held within that ViewPager
via the FragmentPagerAdapter
.
From a user point of view, the application works fine. After several rounds of ViewPager
being removed, I can see the GC reclaiming memory. However, I don't like the fact that those Fragment
s' end of life methods aren't called as I can't do any cleanup within them, and it just doesn't seem 'right'.
Is there a method I can hook into in order to remove the ViewPager
's Fragment
s when the ViewPager
is detached from its parent, perhaps? In other words, when I know that the ViewGroup
is no longer in used, I would perform FragmentTransaction
s somewhere (perhaps in the FragmentPagerAdapter
) to remove those Fragment
s.
Alternatively, I realise that I could just keep the ViewPager
on the right permanently, and dynamically swap the Fragment
s within it. Of course it simply would not matter that at certain times it would only hold one page. If this would be a better way to go then I shall refactor my code to do this, but I would appreciate opinions.
However, I don't like the fact that those Fragments' end of life methods aren't called as I can't do any cleanup within them, and it just doesn't seem 'right'.
They should get cleaned up when the activity is destroyed, if that is not too late for you (e.g., heap issues).
In other words, when I know that the ViewGroup is no longer in used, I would perform FragmentTransactions somewhere (perhaps in the FragmentPagerAdapter) to remove those Fragments.
You did not execute the transactions to put the fragments there. Hence, you cannot readily execute the transactions to remove the fragments. If you switch to FragmentStatePagerAdapter
, and call setAdapter(null)
, it should cause all existing fragments in the pager to be destroyed, by my reading of the source code. FragmentPagerAdapter
never uses remove()
, but FragmentStatePagerAdapter
does, from its destroyItem()
method, and all extant fragments are destroyed via destroyItem()
when a new adapter (or null
) is supplied to setAdapter()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With