Question

I have a page, including WebView. I had android:configChanges="...|orientation|screenSize" in manifest and in worked perfectly well: I scroll view to a particular text, and when screen orientation changes, the WebView is positioned to the same text on the top (this is not same as preserving ScrollY, because of changed width).

Now I changed the design and have different layouts for horizontal and vertical orientation. I prefer to remove 'orientation|screenSize' for the activity to allow reconstructing the page when orientation changes. Everything works fine, but I need to restore the text offset manually.

The closest I could find is getOffsetForPosition(getScrollX(), getScrollY()) for saving offset and bringPointIntoView(offset) for restoring offset, however these function are not backward-compatible: getOffsetForPosition wants API 3+, while bringPointIntoView requires API 14+ (!). In addition they apply to TextView and may be inaccurate with WebView because of HTML tags.

Tried WebView.saveState and WebView.restoreState (called after the page has been loaded). Doesn't seem to work for me.

Yes, I can get calculate scroll position using Paint and FontMetrics, but this is a "dirty trick". Ideally, I prefer to get all parameters from the system and keep the code as much backward compatible as possible.

Was it helpful?

Solution 2

Unfortunately the Javascript doesn't appear to work, since on reloading the HTML page, all stored information will be lost.

Since almost 1.5 month passed since the last answer, here is the way which is not 100% proof, but quite acceptable: save the relative scrolling position as a fraction to the total height:

private float relPosition;

@Override
public void onCreate(Bundle savedState) {

     ........
     relPosition = savedInstanceState.getFloat("WebViewPos");
      .......
}

@Override
public void onSaveInstanceState(Bundle outState) {
      outState.putFloat("WebViewPos",  (float) webView.getScrollY() / webView.getContextHeight();
}


 /*  After the page has been loaded */
   webView.setScrollY((int)(relPosition * webView.getContextHeight()));

As a matter of fact, I haven't got a chance to try it (just changed the design) :)

OTHER TIPS

The WebView has no good Java APIs for this: I think your best bet would be to do this in JavaScript:

  • in window.onscroll find the current paragraph (use document.elementFromPoint[1] for this)
  • in window.onresize scroll to the top of that paragraph[3]

This will have one paragraph's worth of granularity. I'm not sure whether that works for you. If it doesn't you may have some luck using a Range[2] instead of finding the paragraph but I never tried doing that myself.

[1] based on Get element at specified position - JavaScript
[2] like here: Range from pixels
[3] you might want to use a separate JavaScript function that you call from onConfigurationChanged since window.onresize might also be called if the keyboard pops up - this depends on your view hierarchy and activity configuration

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