Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does setOffscreenPageLimit() improve ViewPager performance by retaining more offscreen Fragments?

I have a ViewPager controlling five Fragments. When I swipe from Fragment at index 1 to Fragment at index 0, there's a brief pause in the animation that I'd like to eliminate.

Currently, I'm not calling setOffscreenPageLimit(), so I know that Fragment 0 is being held in memory by the ViewPager while I'm on Fragment 1 in its idle state, because the off screen page limit defaults to 1 (one on either side of the current Fragment).

Here's where it gets confusing. If I call setOffscreenPageLimit(4) on my ViewPager, the pause in the swipe from 1 to 0 animation is gone -- the animation is smooth.

Therefore, I conclude that somehow, keeping Fragments 2-4 in memory improves the animation from Fragment 1 to Fragment 0.

How does retaining Fragments 2-4 improve the swiping animation from Fragment 1 to Fragment 0?

Edit

I ran TraceView, using onPageScrollStateChanged(int state) to determine when to start and stop the trace, as follows:

@Override
public void onPageScrollStateChanged(int state) {
    if (state == 1 && mViewPager.getCurrentItem() == 1) {
        Debug.startMethodTracing("ViewPagerTesting", 100000000);
    }

    if (state == 0 && mViewPager.getCurrentItem() == 0) {
        Debug.stopMethodTracing();
    }
}

It appears that the ViewPager's accessibility methods are causing the UI thread to freeze. When I call setOffscreenPageLimit(4) on the ViewPager, these accessibility methods are way down in the trace -- taking negligible time to finish.

What's causing the delay?

TraceView

like image 633
Matt Logan Avatar asked Jan 24 '14 00:01

Matt Logan


1 Answers

When you use the default implementation of setOffscreenPageLimit() it is only loading the one fragment which is to the right of it. For eg. when you are on index 1, it has index 2 loaded in memory but not index 0, so swiping left will have to generate a new fragment from scratch. To test this theory you might want to use setOffscreenPageLimit(2) and then try swiping index 1->0. This in no way is the optimal solution but will help clear out your doubts about the concept.

like image 131
Shakti Avatar answered Oct 06 '22 20:10

Shakti