How to restore the state of a WebView in a layout “Tabs + Swipe” with ViewPager and FragmentPagerAdapter

In the post Tabs and swipe views Szymon asks how to implement a WebView in order to preserve its state moving from one tab to another in a similar way as explained in How to save the state of a WebView inside a Fragment of an Action Bar.

Starting from the code in Tabs and swipe views

  1. add a permission to access to internet in AndroidManifest.xml
  2. replace the file res/layout/tab3.xml

    where I add a WebView in the third tab;
    as you’ll verify, this WebView still retains its state switching from an adjacent tab (from the second tab in this example) without the need of the code to restore the state of the WebView, instead the WebView is reset switching from a not adjacent tab (from the first tab in this example);
  3. replace the file eu/lucazanini/viewpager/MainActivity.java

    in the internal static class TabFragment:

    • in the onCreate method I initialize the Bundle webViewBundle where I save the state of the WebView
    • in the onCreateView method starting from line 207 I intialize WebView and if webViewBundle is not null I restore the WebView
    • in the onPause method I save the state of the WebView in the Bundle webViewBundle

    if you comment the lines 211 and 213-216 you can verify what I wrote before and i.e. the fragment is not destroyed switching from a tab to another adjacent tab and then also the state of the WebView is preserved:
    this is the default behavior of the ViewPager that retains the selected tab and the two adjacent;
    the code in the lines 211-216 and in onPause method is used to restore the state of the WebView if you select the third tab from the first tab.

Switching to the third tab from the first one, the state of the WebView is restored but the WebView is also reloaded unlike what happens switching from the second tab to the third tab when the entire fragment is stored in memory (you can also see this from the different loading times of the third tab depending on whether you are coming from the first or second tab).
You can change the number of the stored tabs from ViewPager using the setOffscreenPageLimit method whose argument is the number of pages (tabs) before and after the current page to keep in memory.

Consider the following code for eu/lucazanini/viewpager/MainActivity.java

The key point is the line 81 that sets to 2 the number of pages to keep in memory before and after the current one, and in the case of three tabs as in this example it means that all the pages are in memory.
Now the state of WebView is preserved without the need to use a Bundle to save and restore the state because all fragments are stored in memory.

References:
ViewPager

19 Replies to “How to restore the state of a WebView in a layout “Tabs + Swipe” with ViewPager and FragmentPagerAdapter”

  1. Hi Luca,
    One question: Is this compatible with android versions older than 3.0 ?
    Following your tutorials it’s working great on android 4.1 and 4.2 but when i tried it on android 2.3.6 i’m getting:
    java.lang.ClassNotFoundException in dalvik.system.PathClassLoader.findClass
    that exception is thrown at the moment I execute the app.

    I tried installing latest compatibility package because I tought actionbar was not supported. I changed my mainclass from FragmentActivity to ActionBarActivity and set theme to compattheme and it’s working on 4.1 and 4.2 but in android 2.3.6 i’m having the same problem again.
    Any suggestions or workarounds?
    Thanks !

  2. Hi, first i want to say thanks, this is working GREAT.
    The comments in code make it completely clear.
    But i have one issue and maybe you can help me :
    I managed to put 3 webviews in 3 fragments but whenever i rotate the screen , the webviews gets reloaded.
    This is usually solved by overriding on configurationchange and saving the state of the webview but I cannot do that with 3 webviews at the same time, or at least i dont know how. Do you have any idea on how to do that?
    Thanks for your time

    1. If there aren’t changes in layout on in other configurations when you rotate the screen you can try this line in AndroidManifest.xml:
      android:configChanges=”orientation|screenSize”

      See here for more info.

      1. Oohh, i read that article before and tried out but it didn’t work, now i realize I made a a mistake when I wrote the manifest.
        It’s working great, can’t believe it was so easy haha.
        Thanks a lot from Argentina! keep this site up, it’s great !

      1. Same question here?
        all tabs loads the same webpage.. how to change this code so each can have a diferent webpage

        /**
        * A fragment that launches other parts of the demo application.
        */
        public static class TabFragment extends Fragment {

        public static final String ARG_OBJECT = “object”;

        private WebView webView;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

        Bundle args = getArguments();
        int position = args.getInt(ARG_OBJECT);

        int tabLayout = 0;
        switch (position) {
        case 0:
        tabLayout = R.layout.auto;
        break;
        case 1:
        tabLayout = R.layout.fragment_main;
        break;
        case 2:
        tabLayout = R.layout.fragment_main;
        break;
        }

        View rootView = inflater.inflate(tabLayout, container, false);

        webView = (WebView) rootView.findViewById(R.id.browser);
        if (webView != null) {
        webView.setWebViewClient(new WebViewClient());
        webView.loadUrl(“http://www.headgone.net”);
        }

        return rootView;

        }
        }

  3. Hello, thank you for the help but I have a question

    When I open a webpage and click on some link it will open the link but when I want to go back to the first page by clicking the back button, it directly exits the program.
    Need help fast!!!

    Can you write a new article on going back to the primary fragment. Thanks.

    1. You can add this code to MainActivity:

      and replace onTabUnselected and onTabSelected methods:

      1. Sir, Is it a much to ask if I asked you to make a post on displaying three different web pages on three different tabs. I tired the thing you said it works but when I try to replace tab1 and tab2 with tab3 then it doesn’t work. the app exits after I press back button before going to the parent fragment.

        Let me put it clear.
        I want 5 tabs with different web pages. and in every web pages after i click a link I should be able to go back to the previous fragment.
        I would be so much thankful if you could help.

        1. What should the back button do?
          Is it like the back button in the browser, i.e. open the previous page in the web view?
          If so the code in my last comment does this, but it works only for the third tab because of the code in onTabSelected, but you can extend to the other tabs.
          But maybe you want the back button going to a specific fragment or tab.
          If so you can try:

          1. Yes, I want it like back button in the browser. but with this code now when ever I do back it goes to tab 1. I mean when I am in tab 1 and open a link than when i do back it should go to previous link after that may be exit the software.

      2. Hello, first of all thank you for the fantastic tutorials you have on the web.
        I would like to ask you a question, how can I make BACK button works alike in all WebView? If I explain the code as above only works with WebView1 the rest exits the application.

        Thank you very much.

  4. Hi! Thank you so much! This is just what I needed! If you have time can you do a scrollable tabs + swipe version of this?

    Thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.