Mate
Mate

Reputation: 428

WebViews in ViewPager are not loaded/rendered until page is shown

I use a ViewPager with many WebViews, it is for showing an ePub. My Problem is that the WebViews are just rendered/loaded (im not quite sure) wenn their corresponding page becomes visible. After this the page doesn't need to be re-rendered until it is destroyed from the ViewPagerAdapter. The consequence is that there is always a white page for a little while. How can i pre-render the page that it scrolls smooth to next webView (which was not rendered before).

This is my PagerAdapter:

public class MagazineReaderPagerAdapter extends PagerAdapter {

    private MagazineReaderActivity activity;
    private EpubDocument epub;

    public MagazineReaderPagerAdapter(Context ctx, EpubDocument epub)
    {
        activity = (MagazineReaderActivity) ctx;
        this.epub = epub;
    }

    @Override
        public int getCount() {
        return epub.getContentDocuments().size();
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        ReaderWebViewMulti view = new ReaderWebViewMulti(activity);
        view.loadContentDocument(epub.getContentDocuments().get(position), epub);

        ((ViewPager) container).addView(view, 0);
        return view;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view.equals(object);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        ((ViewPager) container).removeView((View) object);
    }
}

ReaderWebViewMulti extends from WebView ind implements a method loadContentDocument wich loads the content via loadDataWithBaseURL.

edit: At activity-oncreate the setOffscreenPageLimit is set to 3

 viewPager.setOffscreenPageLimit(3);

To point out what the problem is, i made a little video on YouTube

From second 4 you can see that every page is just rendered when it is already visible. When i go back everything is fine.

Upvotes: 9

Views: 4627

Answers (3)

girgis abdelmalak
girgis abdelmalak

Reputation: 1

set this property for your application in manifest file

android:hardwareAccelerated="false"

Upvotes: 0

Willum
Willum

Reputation: 69

I had the same problem and fixed it by disabling hardware acceleration for the web view:

webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

See WebView inside ViewPager or ScrollView - weird rendering bug on Android 3.0+

Upvotes: 6

Frank
Frank

Reputation: 12300

I put some thoughts into this. Scrolling the screen 1 pixel would render the right page:

   class SomeClass implements OnPageChangeListener {

        private ViewPager viewPager;

        ...

        viewPager = ...
        viewPager.setOnPageChangeListener(this);

        ...

        @Override
        public void onPageScrollStateChanged(int state) {

            if (state == ViewPager.SCROLL_STATE_IDLE) {
                // viewpager finished scrolling to a page

                viewPager.scrollBy(1, 0);
            }
        }
     }

You would need to check if you are coming from right or left and according to this scroll by -1 or 1 pixels (the page where you are coming from will stay in memory, so you don't need to reload that one). Only at the the very first scroll (after opening the app) the problem described above will still persist.

Drawback: you can see the page scrolling 1 pixel, if you look real closely.

Someone with more time than me could dive into the android code to see what exactly happends when 1 pixel comes into the screen, and mimic some of this behaviour.

Upvotes: 0

Related Questions