【问题标题】:Restore WebView position to same content on orientation change (Android)在方向更改时将 WebView 位置恢复到相同的内容(Android)
【发布时间】:2014-11-15 09:41:58
【问题描述】:

我遇到了WebView 内容滚动位置的问题,这里是:我在纵向模式下将页面向下滑动到一定程度,当我将方向更改为横向时,滚动向上或向下移动。它不显示纵向模式下的确切内容。我确实尝试将清单文件更改为configChanges="keyboardHidden|orientation|screenSize",但没有运气。我确实覆盖了onConfigurationChanged(),但这不起作用。我在这个question 中实现了公认的答案,但没有用。有人可以建议必须做什么,为什么它不起作用?这适用于 Google Nexus Tab,所需的最低 SDK 版本为 14。 谢谢大家。

【问题讨论】:

    标签: android android-webview android-orientation


    【解决方案1】:

    我记得我的应用也遇到过同样的问题。如果我没记错的话,Phil 建议的解决方案不起作用(在某些版本的 Android 上?)。

    我现在正在使用以下方法:

    1. 在onSaveInstanceState中保存WebView的当前滚动位置:outState.putInt(EXTRA_SCROLL_POSITION, webView.getScrollY());
    2. 在 onCreate 中,从 savedInstanceState 中获取最后一个滚动位置,并设置一个自定义的 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;
              }
          }
      });
      

    这很难看,但它对我来说有点用(这不考虑当前的缩放级别等)。该代码有很多地方可以改进,但它基本上可以解决问题。

    【讨论】:

    • 我的活动在改变方向时不会被重新创建。我如何使用 onSaveInstanceState,它只有在失去对另一个应用程序的关注时才会被调用。由于我的活动没有重新创建,所以我也不能使用 onRestoreInstanceState 。 @TomTasche
    • 哦,我明白了。您可以使用 onConfigurationChanged 代替 onRestoreInstanceState,但我不知道您可以用什么替换 onSaveInstanceState。对不起!
    【解决方案2】:

    视图类有一个返回ParcelableonSaveInstanceState() 方法和一个用于恢复状态的onRestoreInstanceState(Parcelable state) 方法。如果我没记错的话,保存的状态包括滚动位置。您需要做的就是将通过调用 WebView 的 onSaveInstanceState() 获得的 Parcelable 保存在片段的 onSaveInstanceState 方法中:

    public void onSaveInstanceState(Bundle savedState) {
    
        super.onSaveInstanceState(savedState);
    
        WebView webView = (WebView) findViewById( ... );
        savedState.putParcelable("myKey", webView.onSaveInstanceState());
    
    }
    

    然后在您的 onCreateView 方法中恢复该状态(如果可用):

    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);
            }
        }
    
        ....
    
    }
    

    【讨论】:

    • 请看一下 Tom Tasche 回答的评论。
    • 如果您不使用片段,那么不,这将不起作用。如果这对您来说是一个足够大的问题,那么可能值得花几个小时尝试基于片段的版本(无论如何,您应该在活动中移动到片段,并且支持库将提供向后兼容性)。
    • 我刚试过,但savedState.putParcelable("myKey", webView.onSaveInstanceState()); 行给了我错误onSaveInstanceState() has protected access in android.view.View
    【解决方案3】:

    尝试使用onSaveInstanceState来保存scrollview的状态在onRestoreInstanceState中恢复方法。你用过Scrollview吗? xml?如果yes然后获取参考到那个视图,当活动恢复然后设置滚动视图的位置 到已保存状态。希望对您有所帮助。

    【讨论】:

    • 请看我对 TomTasche 回答的评论
    猜你喜欢
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    • 1970-01-01
    • 2019-07-26
    • 2017-08-13
    相关资源
    最近更新 更多