【发布时间】:2016-04-22 18:14:47
【问题描述】:
我知道这个问题已经被问过太多次了,而且这里充满了类似的问题。我经历了其中的大部分,我已经研究了几天这个问题,但我还没有找到最终的解决方案。
我可以很容易地避免将configChanges="orientation|screenSize" 添加到包含 WebView 的活动中的所有这些麻烦;我已经对此进行了测试,它按预期工作(WebView 没有重新加载)。 但我真的很想避免这种解决方案。
这是我当前的 WebView 实现:
public class BrowserFragment extends Fragment {
private WebView mWebView;
public BrowserFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mWebView == null) {
mWebView = new WebView(getActivity());
}
return mWebView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return super.shouldOverrideUrlLoading(view, url);
}
});
mWebView.getSettings().setAllowFileAccess(true);
mWebView.getSettings().setBuiltInZoomControls(false);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setSupportZoom(false);
if (savedInstanceState == null) {
mWebView.loadUrl("http://developer.android.com/");
} else {
mWebView.restoreState(savedInstanceState);
}
}
@Override
public void onResume() {
mWebView.onResume();
super.onResume();
}
@Override
public void onPause() {
super.onPause();
mWebView.onPause();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mWebView.saveState(outState);
}
@Override
public void onDestroyView() {
if (getRetainInstance() && mWebView.getParent() instanceof ViewGroup) {
((ViewGroup) mWebView.getParent()).removeView(mWebView);
}
super.onDestroyView();
}
}
至于MainActivity,除了将内容视图设置为以下布局文件外,什么都没有:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/fragment_browser"
android:name="com.example.app.BrowserFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</merge>
请注意,我保留了片段实例,并且还保存了 WebView 的状态,因此我可以稍后恢复相同的状态。这就是文档中关于restoreState 方法的内容:
从给定的 Bundle 中恢复此 WebView 的状态。这种方法 旨在用于 onRestoreInstanceState(Bundle) 并且应该是 调用以恢复此 WebView 的状态。如果在之后调用 这个 WebView 有机会建立状态(加载页面,创建一个 后退/前进列表等)可能会有不良的副作用。 请 请注意,此方法不再为此恢复显示数据 网页视图。
意思是,显示数据不会恢复,但滚动位置之类的东西会恢复(我也对此进行了测试,效果很好)。这就是为什么我要创建 WebView 的新实例,前提是它在 onCreateView 期间为 null 并在 onDestroyView 期间将其从父视图中删除。这取自这个答案:https://stackoverflow.com/a/32801278/40480
这种机制将使旋转过程更加顺畅(没有它,会显示一个完整的空白页面),但不会阻止 WebView 仍然重新加载页面。
有什么办法可以解决这个问题吗?
【问题讨论】:
-
你解决过这个问题吗?我正在处理类似的问题,就像你说的那样,我在这里发现的其他案例无法帮助我。测试您的代码,我注意到问题不仅与屏幕旋转有关,因为如果我们切换选项卡也会重新加载。我认为这与
onCreate()有关,但我还没有找到正确的方法。好吧,欢迎任何关于这个问题的意见,muito obrigado!
标签: android android-fragments webview page-refresh