2

I am using FragmentStatePagerAdapter for listing my Fragmets in ViewPager. Every fragment contains just a WebView. Everything works fine, I just want to use the preload mechanism of PagerAdapter which loads 1 Fragment in advance. This is the simplified code for my Fragment:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
    View view = inflater.inflate(R.layout.ecard_fragment, container, false);
    webview = (WebView) view;
    webview.loadDataWithBaseURL("", HTML, "text/html", "utf-8", "");
    Toast.makeText(getActivity(), "fragment: " + NAME, Toast.LENGTH_SHORT).show();
    return view;
}

I'm sure, that the next Fragment is pregenerated, because Toast is shown in advance. But the WebView is loaded later - just after Fragment is focused. How to force the WebView to load?

peter.bartos
  • 11,855
  • 3
  • 51
  • 62
  • have you tried adapter.setOffscreenPageLimit(3) ? – Artem Zelinskiy May 29 '13 at 11:02
  • i suspect this is probably related to a problem that i had, where i had a WebView set to WRAP_CONTENT that initially sized itself as 0x0 and after being displayed a moment resized itself to match its content. i never found a way to force the WebView to "preload" itself or even to detect when loading was done. i don't think there is a good answer to the problem of preparing a WebView in advance. – j__m May 30 '13 at 01:17

3 Answers3

2

Create your webview in OnCreate() - method and inflate that webview later in your OnCreateView() - method.

Your WebView loaded later because onCreateView() - method is only called if the fragment needs to load the UI to the user.

OnCreate() on the other hand is called before OnCreateView() and can instantiate essential elements of your fragment

DuKes0mE
  • 1,101
  • 19
  • 30
  • Thanks for your response. So, do you suggest inflating WebView in OnCreate and in OnCreateView just return the pre-inflated layout? I tried in right now, but the behaviour is the same. – peter.bartos May 27 '13 at 14:43
  • Uhm yeah, that was my plan. Another option would be using your Activity for preloading your WebView and whenever you change fragments it should push the next wanted content to the activity and you would be able to get that preloaded from your activity. You know what I am getting at? – DuKes0mE May 27 '13 at 15:05
  • I suspect, that the WebView could be the slow element, which won't load the content until the layout is requested. – peter.bartos May 27 '13 at 15:24
  • It should be possible though. Some ppl use for instance 2 Webviews (one invisible, one visible) and flip between those two for preloading stuff – DuKes0mE May 27 '13 at 15:41
  • I'm not selecting this as the answer, because it haven't solved the problem. But thank you for pointing out the difference between OnCreate and OnCreateView. – peter.bartos May 30 '13 at 09:59
0

I have written simple demo project and for me it works fine neighborhood views are pregenerated. This is my code:

public class DrawActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle arg0) {
    setContentView(R.layout.pager);
    ((ViewPager) findViewById(R.id.pager)).setAdapter(new ScreenSlidePagerAdapter(getSupportFragmentManager()));
    super.onCreate(arg0);
}

private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {

    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return new WebViewFragment(position);
    }

    @Override
    public int getCount() {
        return 3;
    }
}

@SuppressLint("ValidFragment")
private class WebViewFragment extends Fragment {

    private WebView mWebView;
    private int pos;

    public WebViewFragment(int pos) {
        this.pos = pos;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mWebView = new WebView(getApplicationContext());
        mWebView.loadDataWithBaseURL("", "<h1> ----------------TEST----------------- " + pos + "</h1>", "text/html", "utf-8", "");
        Toast.makeText(getActivity(), "fragment: " + this.toString(), Toast.LENGTH_SHORT).show();
        return mWebView;
    }

}
}

and xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

And result:

enter image description here

Roman Nazarevych
  • 7,513
  • 4
  • 62
  • 67
  • I think this is exactly what I had in my first try (before optimization with onCreate instead onCreateView). Using the newest Android API, the loading looks much faster and the blank webview is visible just for few milliseconds. Your webview is much more simple, so I think it is generated immediately. – peter.bartos May 29 '13 at 16:35
0

I faced with the same problem and fixed it by disabling hardware acceleration for the WebView:

webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

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

Community
  • 1
  • 1
Sergii
  • 1,521
  • 3
  • 24
  • 37