Question

I'm currently developing an app that uses a ViewPager, the problem is that the way I'm doing it makes it extremely slow to start and takes up tonnes of memory.

I'm implementing the pageradapter like so:

        public MyPagerAdapter(Context context) {
        views = new ArrayList<RelativeLayout>();
        views.add(new SliderLayout(context, "slide 8"));
        views.add(new SliderLayout(context, "slide 1"));
        views.add(new SliderLayout(context, "slide 2"));
        views.add(new SliderLayout(context, "slide 3"));
        views.add(new SliderLayout(context, "slide 4"));
        views.add(new SliderLayout(context, "slide 5"));
        views.add(new SliderLayout(context, "slide 6"));
        views.add(new SliderLayout(context, "slide 7"));
        views.add(new SliderLayout(context, "slide 8"));
        views.add(new SliderLayout(context, "Slide 1"));
    }

All the layoutobjects contain a FrameLayout with a textView and a panel that contains a webview with local html. All the layouts have unique content, that is loaded and inflated when the SliderLayout class is instantiated.

I also attempted to add views on the fly in the instantiateItem method, but that just makes the scrolling more dodgy and will give an OutOfMemory fatal exception if I scroll too fast.

So my question is, what is the best way to implement a ViewPager that contains several unique views (but based on the same layout), so it doesn't consume so much memory and starts quicker?

Was it helpful?

Solution

You must attach your views to pager in instantiateItem() (like you do it in regular adapter's getView() method). In this case ViewPager takes care about memory management. Take a look into demo project in CompatibilityPackage. Actually you can have thousands of pages without any lags.

@Override
public Object instantiateItem(View collection, int position) {
    View v = layoutInflater.inflate(...);
    ...
    ((ViewPager) collection).addView(v,0);
    return tv;
}

@Override
public void destroyItem(View collection, int position, Object view) {
    ((ViewPager) collection).removeView((TextView) view);
}

OTHER TIPS

hm, my idea is to catch the event "onPageChanged()" in the ViewPager and set the webview after the page has changed - or, to preload as example a page so you have the "scroll effect": you do the following:

as example, you have a count of 10 pages. if your viewpager is at page 0, then you instanciate and load the pages 0,1,2. if your viewpager is at screen 4, then you remove the webviews at positions 0,1 and 7,8,9...

in this way you dont need all instances of webviews (webkit consumes a lot of memory) and have some more memory.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top