防止WebView片段在屏幕旋转上重新加载页面
我知道这已经被问过太多次了,并且SO里面充满了类似的问题。我经历了其中的大部分,我一直在研究这个问题几天,我还没有找到最终的解决方案。防止WebView片段在屏幕旋转上重新加载页面
我可以很容易地避免所有这些麻烦添加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恢复显示数据。
意思是,显示数据将不会被恢复,但像滚动位置的东西(我也测试过这个,它很好地工作)。这就是为什么我要创建一个WebView的新实例,只有在onCreateView
期间它是null
并在onDestroyView
期间将其从父视图中删除。这是从这个答案:https://stackoverflow.com/a/32801278/40480
这种机制将使旋转过程更平稳(没有它,一个完整的空白页面显示),但不会阻止WebView仍然重新加载页面。
任何想法我怎么可能可以解决这个问题?
我有一个类似的问题。这是一个有点晚了,但我的解决办法是比你相似,但再次添加web视图中onCreateView布局:
- 创造新的WebView如果实例为null(第一次),并把它添加到布局(在我的情况父一个FrameLayout,在位置0)。
-
如果已经创建(活动重新)只需添加到帧和无效(重要重绘上旋转的WebView)
mFrame = (FrameLayout) mView.findViewById(R.id.dq_fragment_browser_common_frame); if (mWebView == null){ mWebView = new CommonWebView(getContext()); mFrame.addView(mWebView,0); } else { mFrame.addView(mWebView,0); mWebView.invalidate(); }
在你的情况下,我从框架OnDestroyView删除的WebView()是能够在onCreateView再次添加它:
@Override
public void onDestroyView() {
mFrame.removeView(mWebView);
super.onDestroyView();
}
注:我不保存和存储web视图状态,因为它重新加载页面(至少在我的情况)。此外,滚动位置在纵向/横向上通常不匹配,但Chrome浏览器中的问题与我查看的一样。
问候。