Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding fragment activity lifecycle

I have created an android app that uses a ViewPager to swipe through three fragments (each of the three fragments contains a gridview).

I began learning about fragments recently and assumed that after my gridviews were created in their fragments, that each fragment would be in memory and never have to load again.

Recently I noticed that when I swiped from my left fragment, to the middle fragment, then to the right fragment, that the left-most fragment would have to have its gridview filled again with my adapter.

I was just wondering why this happens when I navigate from the left-most fragment to the right-most fragment, but not when I navigate between side-by-side fragments. Does it only keep the most recent fragment in memory and kill the other fragment? Or is there some other reason why an app wouldn't keep all three fragments in memory? My app gets a little laggy and slow when I quickly navigate between fragments, so it would be nice to only have to draw each gridview one time if possible.

I fill my arraylist (used to fill adapter) in onCreate(), and then fill my gridview with the adapter in onActivityCreated(Bundle savedInstanceState)

like image 571
Mat Rez Avatar asked Jan 17 '23 02:01

Mat Rez


2 Answers

The ViewPager keeps a certain amount of off-screen tabs (Fragments, of course) in memory. The default, I believe for all devices, is 1. Thus, when you scroll to the far right, only the one to its left will be kept in memory.

If you want your ViewPager to retain all tabs in memory (careful--this can be hard on the device or other running apps), you can set how many off-screen tabs to keep in memory. To do this, use the setOffscreenPageLimit method of ViewPager on your ViewPager object.

Example:

ViewPager pager = (ViewPager) findViewById(R.id.pager); // Your pager's ID
pager.setOffscreenPageLimit(2); // Will retain 2 off-screen tabs + your selected tab

Hope this helps!

like image 133
Cat Avatar answered Jan 22 '23 01:01

Cat


It's the nature of how a FragmentPagerAdapter and FragmentPagerStateAdapter work. From Google's site:

The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible.

Meaning, your GridView is refilling because your ViewPager killed the view and has to rebuild it.

EDIT: If you need to keep all three fragment Views in memory to speed things up, then you would have to create your own PagerAdapter that stores the views in instantiateItem(ViewGroup, int) inside an Collection of some sort.

Alternatively, if you are using Google's example verbatim, then you probably are doing something like this:

@Override
public Fragment getItem(int position) {
  return ArrayListFragment.newInstance(position);
}

In which case, you're rebuilding a new fragment each time the ViewPager requests one.

like image 20
DeeV Avatar answered Jan 22 '23 01:01

DeeV