2012-08-26 258 views
52

當我旋轉屏幕時,WebView將重新加載整個頁面。我不能有這個,因爲我的一些內容包含動態/隨機材料。當前旋轉時,屏幕會從loadUrl()方法重新加載原始URL。Android - 防止重新加載WebView旋轉

任何想法我的代碼有什麼問題?

MainActivity.java

package com.mark.myapp; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.Menu; 
import android.webkit.WebView; 
import android.webkit.WebViewClient; 

public class MainActivity extends Activity { 

    WebView web; 
    String webURL = "http://www.google.co.uk/"; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     if (savedInstanceState != null) 
      ((WebView)findViewById(R.id.web)).restoreState(savedInstanceState); 

     web = (WebView) findViewById(R.id.web); 
     web.getSettings().setJavaScriptEnabled(true); 
     web.loadUrl(webURL); 
     web.setPadding(0, 0, 0, 0); 
     web.getSettings().setLoadWithOverviewMode(true); 
     web.getSettings().setUseWideViewPort(true); 
     web.getSettings().setSupportZoom(true); 
     web.getSettings().setBuiltInZoomControls(true); 

     web.setWebViewClient(new HelloWebViewClient()); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.activity_main, menu); 
     return true; 
    } 

    private class HelloWebViewClient extends WebViewClient { 
     public boolean shouldOverrideUrlLoading(WebView web, String url) { 
      web.loadUrl(url); 
      return true; 
     } 
    } 

    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if ((keyCode == KeyEvent.KEYCODE_BACK) && web.canGoBack()) { 
      web.goBack(); 
      return true; 
     } 
     return super.onKeyDown(keyCode, event); 
    } 

} 

AndroidManifest.xml中

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.mark.myapp" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="8" 
     android:targetSdkVersion="15" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name=".MainActivity" 

      android:configChanges="orientation|keyboardHidden"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 
    <uses-permission android:name="android.permission.INTERNET"/> 
</manifest> 
+0

我用它自己,可以建議簡化的解決方案是在這裏:http://twigstechtips.blogspot.com/2013/08/android-retain-instance-of-webview.html –

回答

59

我認爲主要的問題是,你調用web.loadUrl(WEBURL); !還當savedInstanceState = NULL

編輯

嘗試:

if (savedInstanceState == null) 
{ 
    web.loadUrl(webURL); 
} 

EDIT2:你還需要和的onSaveInstanceState覆蓋onRestoreInstanceState。

@Override 
protected void onSaveInstanceState(Bundle outState) 
{ 
super.onSaveInstanceState(outState); 
web.saveState(outState); 
} 

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState) 
{ 
super.onRestoreInstanceState(savedInstanceState); 
web.restoreState(savedInstanceState); 
} 
+1

是的!這適用於我(編輯後,蒂姆發現!)!謝謝!你能否解釋爲什麼以及如何工作以及爲什麼這些方法需要覆蓋? – mark

+0

@mark見http://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges – Giuseppe

+0

最後一件事,我真的需要以下if語句:if(savedInstanceState!= null) (( web視圖)findViewById(R.id.web))restoreState(savedInstanceState)。 – mark

49

不需要java編碼。 在你的清單文件中使用它。

android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" 

,如:

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" > 
    <activity 
     android:name="com.Example.WebviewSample.webviewsample" 
     android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity>   
</application> 
+2

你在說什麼改變? –

+0

以下@Mgamerz評論..當事情正在旋轉..這是最糟糕的建議,你可以給 –

+31

Noooooooooooo。甚至不要考慮這樣做。配置更改不限於旋轉。另外,從低內存返回後,實例狀態可以恢復。這裏的問題是,當你這樣做時,配置不會被正確更新。請,沒有人這樣做。 –

2

覆蓋的onConfigChange方法,以避免在AndroidMainfest文件,您的活動上方向變化

重新加載數據。

android:configChanges="orientation|keyboardHidden" 

,並在您的WebView有這些以及設置

webview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
webview.loadUrl("Your URL To Load"); 
4

在清單

<activity 
    ... 
    android:configChanges="orientation|screenSize"> 
14

在標籤(清單)

android:configChanges="orientation|screenSize" 

類添加以下代碼

@Override 
    public void onConfigurationChanged(Configuration newConfig){   
    super.onConfigurationChanged(newConfig); 
    } 
+5

實際上沒有理由重寫'''onConfigurationChanged'''方法,因爲沒有添加自定義功能。簡單地在清單文件中進行更改對我來說是個訣竅。 – i2097i

+0

更完整的答案:https://stackoverflow.com/a/46849736/454780 – trusktr

9

添加在manifest文件android:configChanges="orientation|screenSize"

<activity 
      android:name="com.example.HelloWorld.WebActivity" 
      android:label="@string/title_activity_web" 
      android:configChanges="orientation|screenSize" > 
</activity> 
+0

你可以發佈你的MainActivity關於WebView的功能嗎? – trusktr

5

我不相信,這將不再工作。在我的情況下,使用WebView.restore(Bundle savedInstanceState)恢復狀態仍會觸發URL的重新加載。

縱觀docsrestoreState()你會看到它說:

如果WebView中有機會建立狀態(負載頁面,創建一個後退/前進列表等之後它被稱爲)可能會有不良的副作用。

請注意,這種方法不再恢復的顯示數據這個的WebView。

道具@ e4c5在指着我在正確的方向他answer

當然,行動的極端做法是防止觸發活動破壞/創作方向變化。對於如何做到這一點的文檔是here

0

在manifest文件試試這個:

android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" 
1

將此放在Manifest.xml文件活動:

android:configChanges="orientation|screenSize" 

下面是一個例子:

<activity android:name=".MainActivity" 
      android:label="@string/app_name" 
      android:theme="@style/AppTheme.NoActionBar" 
      android:configChanges="orientation|screenSize"> 
      <intent-filter> 
       <category android:name="android.intent.category.DEFAULT" /> 
      </intent-filter> 
</activity> 
1

如引用here,

注意:從Android 3.2(API級別13)開始,當設備在縱向和橫向 方向之間切換時,「屏幕尺寸」 也會更改。因此,如果要在開發API級別13或更高級別(由minSdkVersion和targetSdkVersion屬性聲明的 )時爲 方向更改而阻止運行時重新啓動,則 除「方向」外還必須包含「screenSize」值爲 。也就是說,你必須decalare android:configChanges =「orientation | screenSize」。但是,如果您的 應用程序的目標級別爲12或更低,則您的活動始終會自行處理此配置更改(即使在更高版本的Android 3.2或更高版本的設備上運行此配置更改 也不會重新啓動您的活動)。

設置爲android:configChanges="orientation|screenSize"您的活動將解決此問題。

另外,還要注意以下

記住:當你宣佈你的活動來處理配置 變化,你有責任爲重置您 提供替代的任何元素。如果您聲明自己的活動處理 方向更改,並且圖像應該在 橫向和縱向之間更改,則必須在onConfigurationChanged()期間將每個資源重新分配給每個 元素。