保持对方向变化的WebView内容的滚动位置 [英] Maintain WebView content scroll position on orientation change

查看:262
本文介绍了保持对方向变化的WebView内容的滚动位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Android上的浏览器2.3+做好在保持内容上改变了方向的滚动位置。

The browsers in Android 2.3+ do a good job at maintaining the scrolled position of content on an orientation changed.

我试图达到同样的事情,我显示内的活动,但没有成功的WebView。

I'm trying to achieve the same thing for a WebView which I display within an activity but without success.

我测试过清单的变化(安卓configChanges =方向| keyboardHidden),以避免因为不同的纵横比的滚动位置不被设置为我想要的不过旋转活动娱乐。此外,这是不可以我的一个解决方案,我需要在纵向和横向不同的布局。

I've tested the manifest change (android:configChanges="orientation|keyboardHidden") to avoid activity recreation on a rotation however because of the different aspect ratios the scroll position does not get set to where I want. Furthermore this is not a solution for me as I need to have different layouts in portrait and landscape.

我已经试过保存web视图状态和恢复,但显示在顶部此resuls的内容了。

I've tried saving the WebView state and restoring it but this resuls in the content being displayed at the top again.

此外试图使用 onPageFinished 滚动 scrollTo 不,虽然web视图的高度甚至工作是非-Zero在此点。

Furthermore attempting to scroll in onPageFinished using scrollTo doesn't work even though the height of the WebView is non-zero at this point.

任何想法?提前致谢。彼得。

Any ideas? Thanks in advance. Peter.

部分解决:

我的同事设法通过JavaScript解决方案滚动工作。对于简单的滚动到相同的垂直位置,web视图的Y滚动位置保存在的onSaveInstanceState 状态。下面,然后添加到 onPageFinished

My colleague managed to get scrolling working via a javascript solution. For simple scrolling to the same vertical position, the WebView's 'Y' scroll position is saved in onSaveInstanceState state. The following is then added to onPageFinished:

public void onPageFinished(final WebView view, final String url) {
    if (mScrollY > 0) {
        final StringBuilder sb = new StringBuilder("javascript:window.scrollTo(0, ");
        sb.append(mScrollY);
        sb.append("/ window.devicePixelRatio);");
        view.loadUrl(sb.toString());
    }
    super.onPageFinished(view, url);
}

你得到了轻微的闪烁作为内容跳转从一开始就新的滚动位置,但很难被发现。下一步是尝试一个基于百分比法(基于高度差),并探讨具有的WebView保存和恢复其状态。

You do get the slight flicker as the content jumps from the beginning to the new scroll position but it is barely noticeable. The next step is try a percentage based method (based on differences in height) and also investigate having the WebView save and restore its state.

推荐答案

要在方向变化恢复的WebView的当前位置恐怕你将不得不做手工。

To restore the current position of a WebView during orientation change I'm afraid you will have to do it manually.

我用这个方法:

  1. 滚动计算的实际百分比在web视图
  2. 将其保存在onRetainNonConfigurationInstance
  3. 恢复的WebView的位置时,它的重新

由于web视图的宽度和高度没有波泰特和横向模式相同,我使用的百分比来重新present用户滚动位置。

Because the width and height of the WebView is not the same in portait and landscape mode, I use a percent to represent the user scroll position.

步骤一步:

1)计算滚动的实际百分比在web视图

1) Calculate actual percent of scroll in the WebView

// Calculate the % of scroll progress in the actual web page content
private float calculateProgression(WebView content) {
    float positionTopView = content.getTop();
    float contentHeight = content.getContentHeight();
    float currentScrollPosition = content.getScrollY();
    float percentWebview = (currentScrollPosition - positionTopView) / contentHeight;
    return percentWebview;
}

2),将它保存在onRetainNonConfigurationInstance

2) Save it in the onRetainNonConfigurationInstance

保存进度只是方向改变之前

Save the progress just before the orientation change

@Override
public Object onRetainNonConfigurationInstance() {
    OrientationChangeData objectToSave = new OrientationChangeData();
    objectToSave.mProgress = calculateProgression(mWebView);
    return objectToSave;
}

// Container class used to save data during the orientation change
private final static class OrientationChangeData {
    public float mProgress;
}

3)恢复的WebView的位置时,它的重新

3) Restore the position of the WebView when it's recreated

从方位变化数据获取的进展

Get the progress from the orientation change data

private boolean mHasToRestoreState = false;
private float mProgressToRestore;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    mWebView = (WebView) findViewById(R.id.WebView);
    mWebView.setWebViewClient(new MyWebViewClient());
    mWebView.loadUrl("http://stackoverflow.com/");

    OrientationChangeData data = (OrientationChangeData) getLastNonConfigurationInstance();
    if (data != null) {
        mHasToRestoreState = true;
        mProgressToRestore = data.mProgress;
    }
}

要恢复当前的位置,你将不得不等待重新加载页面( 这种方法是有问题的,如果你的网页需要很长的时间来加载)

To restore the current position you will have to wait the page to be reloaded ( this method can be problematic if your page takes a long time to load)

private class MyWebViewClient extends WebViewClient {
    @Override
    public void onPageFinished(WebView view, String url) {
        if (mHasToRestoreState) {
            mHasToRestoreState = false;
            view.postDelayed(new Runnable() {
                @Override
                public void run() {
                    float webviewsize = mWebView.getContentHeight() - mWebView.getTop();
                    float positionInWV = webviewsize * mProgressToRestore;
                    int positionY = Math.round(mWebView.getTop() + positionInWV);
                    mWebView.scrollTo(0, positionY);
                }
            // Delay the scrollTo to make it work
            }, 300);
        }
        super.onPageFinished(view, url);
    }
}

在我的测试中,我遇到了你需要的是调用,以滚动的工作​​等待了一点onPageFinished方法之后。前人的精力300ms的是好的。这种延迟使显示轻弹(第一陈列在滚动0然后去到正确的位置)。

During my test I encounter that you need to wait a little after the onPageFinished method is called to make the scroll working. 300ms sould be ok. This delay make the display to flick (first display at scroll 0 then go to the correct position).

也许有一种别的更好的办法来做到这一点,但我不知道。

Maybe there is an other better way to do it but I'm not aware of.

这篇关于保持对方向变化的WebView内容的滚动位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆