【问题标题】:WebView reloading when Fragment in ViewPager is retained form BackStack当 ViewPager 中的 Fragment 从 BackStack 保留时 WebView 重新加载
【发布时间】:2013-04-22 18:41:56
【问题描述】:

这是基本Fragment 的代码,其中包含WebView
WebFragment.java

public class WebFragment extends Fragment {
String TAG = "WebFragment";
private WebView webView;
private String currentUrl = "http://www.google.com";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    return inflater.inflate(R.layout.webview_layout, null);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    webView = (WebView) getView().findViewById(R.id.helloWebview);
    initWebView();
    webView.loadUrl(currentUrl);
}

@SuppressLint("SetJavaScriptEnabled")
private void initWebView() {
    webView.getSettings().setJavaScriptEnabled(true);
    webView.addJavascriptInterface(new JavaScriptInterface(), "HTMLOUT");
    webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            Log.e(TAG, "Loding...");
            super.onPageStarted(view, url, favicon);
        }
    });
}

class JavaScriptInterface {
    public void showHTML(String html) {
    }
}
}

我还有两个基本片段(没有WebView)。然后我使用FragmentAdapter将所有这3个Fragments放入ViewPagerWebFragmentFragment1Fragment2分别)。我在AndroidManifest.xml 中添加了android:configChanges="orientation|screenSize"(所以WebView 不会在配置更改时重新生效)。
现在我的问题是,在运行应用程序时,我将ViewPager 的第一页(WebFragmet)更改为第二页(Fragment1),然后我又回到了第一页。所以没问题WebFragment 就是这样。

现在我再次将ViewPager 更改为WebFragment-->Fragment1-->Fragment2 并通过反转上述操作的方向返回到第一页。但当时我看到WebFragment中的WebView正在重新加载。

还有一个问题,每当WebView 开始加载时,我都会看到 2 个类似的日志条目。

WebFragment Loading...
WebFragment Loading...

所以我的问题是:
1) 当WebFragmentBackStack 保留时,如何防止WebView 重新加载?
2) 为什么在这里WebView 加载两次?

只要看到这个问题并帮助我(Prevent WebView reloads in FragmentPagerAdapter?)。

【问题讨论】:

    标签: android android-fragments android-webview android-viewpager back-stack


    【解决方案1】:

    在您定义 viewpager 的主要活动中

    在 viewpager 声明之后,如下行: ViewPager viewpager = (ViewPager) findViewById(R.id.pager);

    添加这一行:

    viewpager.setOffscreenPageLimit(2);
    

    这将防止您的片段重新创建以滑动两个屏幕,因此当您在 viewpager 中从第 3 页返回到第 1 页时,您的 webview 将不会重新加载。

    【讨论】:

    • @Chirag Shah 实际上我知道这一点(viewpager.setOffscreenPageLimit(2);) 但如果我的ViewPager 中有5 个或更多FragmentsWebView 如果我设置viewpager.setOffscreenPageLimit(5+);,那将是一个不好的选择,对吗?你说什么?
    • 你能回答我的第二个问题吗?
    • 你能解释一下设置 offscreenlimit 有多糟糕吗?我认为防止你的片段被重新创建会很好。不是吗?我不确定你的第二个问题?可能是因为你正在调用 initWebView() 方法并且还写了这一行:webView.loadUrl(currentUrl);所以它被调用了两次。@VishalVijay
    • @Chirag Shah,我没有在initWebView() 中调用`webView.loadUrl(currentUrl);`,所以它不应该调用两次。
    • @Chirag Shah,使用viewpager.setOffscreenPageLimit(5+); 的问题是内存和性能。如果我将 5+ 设置为屏幕外限制。所有 5+ Fragments 都将在内存中,因此 Android 在低规格设备中可能存在性能问题。
    【解决方案2】:

    这是一个典型的案例,通过简单的补丁修复覆盖android:configChanges 来解决问题。不幸的是,发生配置更改的原因有多种。所以简单地捕捉屏幕尺寸的变化会错过很多......正如你所发现的那样。

    首先,彻底删除android:configChanges。然后将以下内容添加到您的 WebView 片段中。

    protected void onSaveInstanceState(Bundle outState) {
      webView.saveState(outState);
    }
    

    调整您的 WebView 片段的 onActivityCreated 方法以包含以下内容:

    public void onActivityCreated(Bundle savedInstanceState) {
        webView = (WebView) getView().findViewById(R.id.helloWebview);
        initWebView();
    
        if (savedInstanceState != null)
            webView.restoreState(savedInstanceState);
        else
            webView.loadUrl(currentUrl);
    

    }

    这应该会让你朝着正确的方向前进。注意,调用WebView 的saveState() 不会保存显示数据。例如,输入标签不会保留用户输入。您需要手动解析网页以保留该数据。根据您使用 WebView 的目的,这将是一个很大的痛苦。

    【讨论】:

      【解决方案3】:

      片段像这样使用。

      A extends Fragment
      
      {
      
         static  WebView w;
      
         View v;
      
         private Handler handler = new Handler(){
      
          @Override
          public void handleMessage(Message message) {
      
              switch (message.what) {
                  case 1:{
                      webViewGoBack();
                  }break;
              }
          }
      
          private void webViewGoBack() {
              w.goBack();
      
              // TODO Auto-generated method stub
      
          }
      };
      
      @Override
      
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle    savedInstanceState){
      
       v = inflater.inflate(R.layout.webs, container, false);
      
       w=(WebView)v.findViewById(R.id.webView1);
      
      //w.loadUrl("");
      
      }
      
       w.setOnKeyListener(new OnKeyListener(){
      
       @Override
      
       public boolean onKey(View v, int keyCode, KeyEvent event) {
      
                  // TODO Auto-generated method stub
         if((keyCode==KeyEvent.KEYCODE_BACK)&& w.canGoBack())
      
                  {
      
                      handler.sendEmptyMessage(1);
      
                      return true;
      
                  }
                  return false;
              }
      
           });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-22
        • 1970-01-01
        相关资源
        最近更新 更多