103 votes

Android - Empêcher le rechargement d'un WebView lors d'une rotation

Lorsque je fais pivoter mon écran, le WebView recharge la page entière. Je ne peux pas faire cela car une partie de mon contenu contient des éléments dynamiques/aléatoires. Actuellement, lorsqu'il est tourné, l'écran recharge l'URL d'origine à partir de la méthode loadUrl().

Une idée de ce qui ne va pas dans mon code ?

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>

118voto

Giuseppe Points 551

Je pense que le problème principal est que vous appelez web.loadURL(webURL) ; également lorsque savedInstanceState != null

EDITAR

Essayez :

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

EDIT2 : Vous avez également besoin des surcharges onSaveInstanceState et 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);
}

Note : Veuillez également ajouter dans votre AndroidManifest.xml dans votre activité Android:configChanges="orientation|screenSize". Merci

68voto

Aby Mathew Points 232

EDIT : J'ai trouvé une solution plus appropriée.

NOUVEAU :

Sur AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.Example.WebviewSample">
    <application
        <activity android:name=".WebViewActivity"
            <!-- ADD THIS -->
            android:configChanges="orientation|screenSize">
        </activity>
    </application>
</manifest>

Sur WebViewActivity.java ajoutez ceci à onCreate() méthode

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    wView = (WebView) findViewById(R.id.webView);
    if (savedInstanceState == null) {
        wView.loadUrl("https://google.com");
    }
}

également mettre à jour onSaveInstanceState

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

y onRestoreInstanceState

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
    super.onRestoreInstanceState(savedInstanceState);
    wView.restoreState(savedInstanceState);
}

OLD :

Aucun codage Java n'est nécessaire. Utilisez ceci dans votre fichier manifeste.

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

comme :

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

22voto

01wifi01 Points 385

Dans l'étiquette (manifeste)

android:configChanges="orientation|screenSize"

15voto

Rasel Points 1

Ajout de android:configChanges="orientation|screenSize" en manifeste fonctionne pour moi

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

8voto

Ranjeev Mahtani Points 178

Je ne crois pas que ça va encore marcher. Dans mon cas, la restauration de l'état en utilisant WebView.restore(Bundle savedInstanceState) déclenche toujours un rechargement de l'url.

En regardant le docs para restoreState() vous verrez qu'il est écrit :

S'il est appelé après que ce WebView ait eu l'occasion de construire un état (charger des pages, créer une liste avant/arrière, etc.), il peut y avoir des effets secondaires indésirables.

et

Veuillez noter que cette méthode ne restaure plus les données d'affichage de ce WebView.

Félicitations à @e4c5 pour m'avoir indiqué la bonne direction dans son réponse

Et bien sûr, la solution extrême serait d'empêcher les changements d'orientation de déclencher la destruction/création d'activités. La documentation sur la manière de procéder est la suivante aquí

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X