59 votes

Android:configChanges="orientation" ne fonctionne pas avec les fragments

J'essaie simplement d'adapter certaines de mes applications à HoneyComb.

Le problème auquel je suis confronté est la destruction de mon activité lors du changement d'orientation (paysage/portrait).

Lorsque j'utilisais une activité classique, j'écrivais dans le manifeste :

Mais maintenant, toutes ces lignes ne fonctionnent plus !

Existe-t-il une solution de contournement pour cela ?

Mon code :

    <activity android:name=".TwitterActivity" android:label="@string/app_name"
        android:configChanges="keyboardHidden|orientation" />

    <activity android:name=".TwitterActivity$AppListFragment"
    android:configChanges="keyboardHidden|orientation"  />

78voto

PJL Points 5865

D'après mon expérience avec Honeycomb 3.0 et la bibliothèque de compatibilité (r1).

configChange="orientation" fonctionne avec les fragments pour empêcher la recréation de l'activité (à laquelle il est appliqué) lors d'un changement d'orientation. Si vous voulez que le fragment ne doit pas être recréé lors de la recréation de l'activité, puis appeler setRetainInstance sur onCreate .

Sauf si j'ai raté quelque chose, je ne comprends pas bien votre deuxième entrée du manifeste, n'est-ce pas ? AppListFragment a Fragment ? Si c'est le cas, pourquoi figure-t-il dans votre manifeste ?

Ver Réponse SO pour les nouveaux qualificatifs qui sont susceptibles de causer ce problème si vous ciblez le sdk 13, je suggère d'essayer android:configChanges="orientation|screenSize"

37voto

JustLearningAgain Points 538

J'ai eu un problème très similaire mais j'ai dû faire quelques ajouts pour qu'il fonctionne avec différentes versions (y compris ICS).

Dans l'activité principale de l'application, j'ai ajouté une version légèrement différente de celle proposée par Jason.

<activity
android:name=".MyMainActivity"
android:configChanges="orientation|keyboardHidden|screenSize" 
android:label="@string/app_name" >

Je l'ai fait fonctionner sur un pré-Honeycomb avec :

           <activity
        ....
        android:configChanges="orientation|keyboardHidden" 
        .... >

J'ai dû faire le premier exemple pour qu'il fonctionne sur toutes les versions. J'utilise actuellement les fragments et ActionBarSherlock pour la rétrocompatibilité.

J'ai aussi changé la façon dont je sauvegardais et rechargeais :

        public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        // Set up webview object
        View v = inflater.inflate(R.layout.webview_layout, container, false);
        webview = (WebView)v.findViewById(R.id.webview_fragment);
        webview.getSettings().setJavaScriptEnabled(true);

        // Check to see if it has been saved and restore it if true
        if(savedInstanceState != null)
        {
            if (savedInstanceState.isEmpty())
                Log.i(tag, "Can't restore state because bundle is empty.");
            else
            {
                if (webview.restoreState(savedInstanceState) == null)
                    Log.i(tag, "Restoring state FAILED!");      
                else
                    Log.i(tag, "Restoring state succeeded.");      
            }

        }
        else 
        {
            // Load web page
            webview.setWebViewClient(new MyWebViewClient());
            webview.getSettings().setPluginsEnabled(true);
            webview.getSettings().setBuiltInZoomControls(false); 
            webview.getSettings().setSupportZoom(false);
            webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);   
            webview.getSettings().setAllowFileAccess(true); 
            webview.getSettings().setDomStorageEnabled(true);
            webview.loadUrl(mTabURL);       
        }
        return v;
    }

Le code de la méthode de sauvegarde de l'état de l'instance :

       @Override
    public void onSaveInstanceState(Bundle outState)
    {
        if(webview.saveState(outState) == null)
            Log.i(tag,"Saving state FAILED!");
        else
            Log.i(tag, "Saving state succeeded.");      
    }

J'espère que cela vous aidera.

34voto

Thomas Gatt Points 410

Jusqu'à l'API 13, une nouvelle valeur était attribuée à l'attribut configChanges, screenSize

Par conséquent, si vous utilisez de grands écrans, veillez à ajouter screenSize dans votre attribut configChanges :

        android:configChanges="orientation|keyboardHidden|screenSize"

9voto

Aarun Points 719

À partir d'Android 3.2 (niveau 13 de l'API), la "taille de l'écran" change également lorsque l'appareil passe de l'orientation portrait à l'orientation paysage. Ainsi, si vous souhaitez empêcher les redémarrages de l'exécution en raison d'un changement d'orientation lorsque vous développez pour le niveau 13 de l'API ou une version ultérieure (comme déclaré par les attributs minSdkVersion et targetSdkVersion), vous devez inclure la valeur "screenSize" en plus de la valeur "orientation". Autrement dit, vous devez décaler Android:configChanges="orientation|screenSize". Toutefois, si votre application vise le niveau 12 de l'API ou un niveau inférieur, votre activité gère toujours ce changement de configuration elle-même (ce changement de configuration ne redémarre pas votre activité, même lorsqu'elle fonctionne sur un appareil Android 3.2 ou supérieur).

2voto

Vera Points 956

Je sais que c'est une réponse tardive, mais j'ai récemment été confronté à ce problème et j'ai pu le résoudre pour l'activité Fragment.

1) Au manifeste,

      android:configChanges="orientation|keyboardHidden|screenSize"

2) Dans le fichier de classe, surchargez le onSaveInstanceState(Bundle outState). C'est tout ! Bon appétit :)

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