Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restore WebView position to same content on orientation change (Android)

I am facing an issue with WebView content scroll position and here it is: I am scolling down the page to some extent in portrait mode and when I change orientation to landscape the scroll moves up or down. It doesnt show the exact content which is there in portrait mode. I did try doing changes in Manifest file as configChanges="keyboardHidden|orientation|screenSize" but no luck. I did override onConfigurationChanged() but that did not work. I implemented the accepted answer in this question but of no use. Can somebody suggest what has to be done and why doesn't it work? This is for Google Nexus Tab and the min required SDK version is 14. Thanks all.

like image 801
Lavanya Avatar asked Jun 07 '13 08:06

Lavanya


2 Answers

I remember facing the same problem with my app. If I'm not mistaken, the solution suggested by Phil doesn't work (on some versions of Android?).

I'm using the following approach now:

  1. in onSaveInstanceState save the current scroll position of the WebView: outState.putInt(EXTRA_SCROLL_POSITION, webView.getScrollY());
  2. in onCreate, get the last scroll-position from the savedInstanceState and set a custom WebViewClient:

    setWebViewClient(new WebViewClient() {
    
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
    
            if (!scrolled) {
                postDelayed(new Runnable() {
    
                    @Override
                    public void run() {
                        scrollBy(0, scroll);
                    }
                }, 250);
    
                scrolled = true;
            }
        }
    });
    

This is ugly as hell, but it kinda works for me (this doesn't account for the current zoom-level, etc). There's lot about that code you could improve, but it basically does the trick.

like image 152
TomTasche Avatar answered Oct 06 '22 04:10

TomTasche


View classes have an onSaveInstanceState() method that returns a Parcelable, and an onRestoreInstanceState(Parcelable state) method to restore the state. If I recall correctly, the saved state includes scroll position. All you need to do is save the Parcelable you get from a call to the WebView's onSaveInstanceState() in your fragment's onSaveInstanceState method:

public void onSaveInstanceState(Bundle savedState) {

    super.onSaveInstanceState(savedState);

    WebView webView = (WebView) findViewById( ... );
    savedState.putParcelable("myKey", webView.onSaveInstanceState());

}

Then in your onCreateView method you restore that state, if available:

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

    ...

    if (savedInstanceState != null) {
        WebView webView = (WebView) findViewById( ... );
        Parcelable savedState = savedInstanceState.getParcelable("myKey");
        if (savedState != null) {
           webView.onRestoreInstanceState(savedState);
        }
    }

    ....

}
like image 33
Phil Haigh Avatar answered Oct 06 '22 04:10

Phil Haigh