8

I have a ViewPager2 in one of my fragments (let's call it fragment A). the viewpager uses a FragmentStateAdapter to create a number of fragments as the children (let's call these fragments children). when the user clicks on a button in fragment A, I replace it with fragment B.

now when the user clicks on device back button to come back to fragment A, I can see that children are automatically restored by the system (they are not shown in viewpager, but the onCreateView method of them are called and the saved bundle is delivered to them). how to avoid this behavior. I do not want children to be automatically recreated and restored.

Soheil
  • 587
  • 4
  • 20
  • You have a container (A) that contains a ViewPager with N Children. You then replace this container (A) with _another container_ (B). This means all the Fragments (Children) in the ViewPager are gone since their parent (A) is now gone. What exactly do you expect (or want) to happen here? You can't possibly *want* to keep all the viewPager children in memory, this would be a potential waste (not to mention that you may not even have that amount of memory). So what is the issue here? – Martin Marconcini Nov 09 '21 at 12:27
  • @MartinMarconcini the issue is that when I pop fragment A from backstack (by clicking back button), the fragments of viewpager get automatically recreated (onCreateView method of them gets called). this is what I don't understand why is happening and how to avoid. – Soheil Nov 09 '21 at 12:46
  • Well the ViewPager is a View (In fact, ViewPager2 is basically a RecyclerView). When a fragment is popped out/hidden/removed, its view is destroyed to release the resources, this naturally includes the children of said view. This is how Fragments works. If you want to retain their state, you do so, and then when the view is recreated, you restore the state. Trying to prevent the Fragment from destroying its view is not a good idea. – Martin Marconcini Nov 09 '21 at 13:17
  • @MartinMarconcini I think you have misunderstood the issue. when I replace fragment A, I do want all its children including the viewpager to get destroyed. but when I come back to fragment A, I can see that even before saving any item in viewpager, `onCreate` method of fragments in viewpager is called. why?! who is instantiating these fragments while I have not yet added any data to viewpager?! – Soheil Nov 09 '21 at 13:26
  • Indeed I did misunderstand it; so can you share the code where you create your ViewPager? If the viewPager is created, it will be associated with an Adapter and it will trigger its `offscreenPageLimit` creation, but I'm sure there's more than meet the eye in there. I'm sure either VP or the FragmentManager is being "preemptively smart" and is getting ready to restore the previous state. – Martin Marconcini Nov 09 '21 at 13:54

2 Answers2

5

In a nutshell, a ViewPager keeps an internal list of items (that respresent 'pages'). The number of items in this list is based on the the mOffScreenPageLimit value. By default it's set to 1, but you can change it by calling setOffscreenPageLimit(int limit). For example :

viewpager.offscreenPageLimit = 3
Hossein
  • 439
  • 3
  • 9
  • when I replace fragment A with another fragment, I set `viewPager=null` and `viewPagerAdapter=null` in `onDestroyView` method and so the viewpager must be garbage collected. so when I come back to fragment A, why `onCreateView` of fragments in viewpgaer gets called **before** I add any item to viewpager?! – Soheil Nov 09 '21 at 12:51
1

Try this in your onCreateView method:

if(view ==null)
{
       //your oncreate view code
 }
Danish
  • 676
  • 5
  • 10
  • you mean to save the view of fragment in a variable and then restore it? obviously saving the views consumes a lot of memory and is not meaningful. – Soheil Feb 08 '21 at 16:11