21

下面是一個基本Fragment的代碼,其中包含WebView
WebFragment.java
當ViewPager中的片段被保留時,WebView重新加載BackStack

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) { 
    } 
} 
} 

我有2個以上基本片段還(其不具有WebView)。然後我使用FragmentAdapter將所有這些3 Fragments分別放在ViewPagerWebFragment,Fragment1Fragment2)中。並且我在AndroidManifest.xml中添加了android:configChanges="orientation|screenSize"(因此WebView在配置更改時不會實現)。
現在我的問題是,在運行應用程序時,我將ViewPager的第1頁(WebFragmet)更改爲第2頁(Fragment1),並且我又回到了第1頁。所以沒問題,WebFragment就是這樣。

現在我再次改變ViewPager這樣WebFragmentFragment1Fragment2並且通過顛倒上述動作的方向回到第1頁。但那時我看到WebViewWebFragment正在重新加載。

還有一個問題,只要WebView開始加載,我可以看到2個日誌條目。

WebFragment Loading... 
WebFragment Loading... 

所以我的問題是:
1)如何防止WebView重裝時WebFragmentBackStack保留?
2)爲什麼在這裏WebView加載兩次?

只看到這個問題,幫我(Prevent WebView reloads in FragmentPagerAdapter?)。

回答

26

在您的主要活動,你必須viewpager

定義viewpager像這條線的聲明之後: ViewPager viewpager = (ViewPager) findViewById(R.id.pager);

加入這一行:

viewpager.setOffscreenPageLimit(2); 

這將防止您的片段從重建直到兩個屏幕的滑動,所以當你從viewpager中的第3頁返回到第1頁時,你的webview將不會重新加載。

+0

很確定這是正確的答案。 – Wamasa 2013-05-09 14:04:34

+0

@Chirag Shah其實我知道這一點('viewpager.setOffscreenPageLimit(2);'')但如果我設置'viewpager.setOffscreenPageLimit(5+);如果我有'WebView'我'ViewPager'中有5個或更多'Fragments'; ',這將是一個糟糕的選擇,究竟?你說的話? – 2013-05-09 18:36:51

+0

你能回答我的第二個問題嗎? – 2013-05-09 18:38:07

2

好的碎片就是這樣使用的。

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

    }); 
4

這是犧牲品的首要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的方式,這將是一大痛苦。

相關問題