Non ricaricare l'applicazione quando l'orientamento cambia


152

Semplicemente non ho bisogno di nulla da cambiare quando lo schermo viene ruotato. La mia app visualizza un'immagine casuale al primo caricamento e la rotazione del dispositivo non deve selezionare un'altra immagine casuale. Come posso (semplicemente) fermare questo comportamento?


1
È anche possibile bloccare (e possibilmente sbloccare) l'orientamento dello schermo dal codice. Basta chiamare Screen.lockOrientation(this)da github.com/delight-im/Android-BaseLib/blob/master/Source/src/im/… per questo. Permette lo sblocco a cui il manifest non lo fa.
Caw

@Escobar Ceaser Qual è la soluzione corretta per questa domanda. Anche io ho gli stessi requisiti.
Prabs,

Vorrei farlo programmaticamente nel codice.
pollaris,

Risposte:


249

Esistono generalmente tre modi per farlo:

  1. Come suggerito da alcune delle risposte, è possibile distinguere i casi in cui l'attività è stata creata per la prima volta e da cui è stata ripristinata savedInstanceState. Questo viene fatto sovrascrivendo onSaveInstanceStatee controllando il parametro di onCreate.

  2. È possibile bloccare l'attività in un orientamento aggiungendo android:screenOrientation="portrait"(o "landscape") a <activity>nel manifest.

  3. Potresti dire al sistema che intendevi gestire le modifiche dello schermo specificando android:configChanges="orientation|screenSize"il <activity>tag. In questo modo l'attività non verrà ricreata, ma riceverà invece una richiamata (che è possibile ignorare in quanto non è utile per te).

Personalmente andrei con (3). Ovviamente se il blocco dell'app su uno degli orientamenti va bene con te, puoi anche andare con (2).


13
Quindi per # 3 stai dicendo che tutto quello che devo fare è aggiungere quella riga al mio manifest? Perché non funziona.
Jimmy D,


16
@EscobarCeaser, per Android 3.2 e versioni successive, è necessarioandroid:configChanges="orientation|screenSize"
Pacerier il

9
android:configChanges="orientation|screenSize"per me va bene. Grazie @Pacerier
Don Larynx,

1
per favore, aggiorna il tuo caso di risposta n. 3 con un android:configChanges="orientation|screenSize"valore per API> = 13, perché molte persone vedono la tua risposta come principale!
Radistao,

215

La risposta di Xion era vicina, ma # 3 ( android:configChanes="orientation") non funzionava a meno che l'applicazione non abbia un livello API di 12 o inferiore.

Nel livello API 13 o superiore, le dimensioni dello schermo cambiano quando cambia l'orientamento, quindi ciò provoca comunque la distruzione e l'avvio dell'attività quando l'orientamento cambia.

Aggiungi semplicemente l'attributo "screenSize" come ho fatto di seguito:

<activity
    android:name=".YourActivityName"
    android:configChanges="orientation|screenSize">
</activity>

Ora, quando si cambia l'orientamento (e le dimensioni dello schermo cambiano), l'attività mantiene il suo stato e onConfigurationChanged()viene chiamata. Ciò manterrà tutto ciò che è sullo schermo (ad esempio: pagina Web in una visualizzazione Web) quando l'orientamento cambia.

Ho imparato questo da questo sito: http://developer.android.com/guide/topics/manifest/activity-element.html

Inoltre, questa è apparentemente una cattiva pratica, quindi leggi il link seguente su Gestione delle modifiche di runtime:

http://developer.android.com/guide/topics/resources/runtime-changes.html


2
Grazie ... il suo lavoro dopo aver aggiunto "screenSize" con "orientamento"
Pratik Butani,

Funziona con Samsung Galaxy Nexus Android 4.2.1! android:configChanges="orientation|screenSize"
Vincent Ducastel,

Sorprendente. Ho lavorato attraverso il codice per così tante ore per risolvere un problema che ho avuto con la ricarica delle attività e un video a partire dall'inizio. Ed ecco la soluzione! ++++ 1
Mathias Asberg,

6
Cattiva pratica? Pfft, le persone nella vita reale hanno delle scadenze e se funziona, funziona;)
Kacy,

Se questa è una cattiva pratica, allora perché ha ottenuto così tanti voti ??
Sharp Edge,

26

Devi solo andare su AndroidManifest.xmle dentro o nelle etichette delle tue attività, devi digitare questa riga di codice come qualcuno ha detto lassù:

android:configChanges="orientation|screenSize"

Quindi, avrai qualcosa del genere:

<activity android:name="ActivityMenu"
android:configChanges="orientation|screenSize">
</activity>

Spero funzioni!


non sta caricando il mio layout-layout di terra. :( non ha funzionato per me
piyush poriya,

16
<activity android:name="com.example.abc" 
 android:configChanges="orientation|screenSize"></activity>

Basta aggiungere android:configChanges="orientation|screenSize"nella scheda attività del file manifest.

Pertanto, l'attività non verrà riavviata quando l'orientamento cambia.


Sta funzionando. Ma quando sto usando un layout separato per ogni orientamento layout.xml e layout-land.xml. applica il layout orizzontale per entrambi gli orientamenti. Se uso solo "l'orientamento", è dare ciò che mi aspetto ma ricaricare. Puoi aiutarmi su questo?
Karthikeyan Ve,

1
@KarthikeyanVe Questo è il problema quando stai cercando di imbrogliare. Dovrete avere a riavviare l'attività di layout di cambiamento. Vai avanti e usa semplicemente la soluzione reale, che sta usando onSaveInstanceState()e onCreate().
Marc Plano-Lesay,

@ MarcPlano-Lesay e come posso supporre di farlo?
Ahsan,

@Weaboo la soluzione attuale è collegata alla domanda: developer.android.com/guide/topics/resources/…
Marc Plano-Lesay

@ MarcPlano-Lesay Ho un layout separato per la modalità verticale e orizzontale, se apro la mia app in modalità orizzontale o verticale funziona benissimo ma ogni volta che provo a cambiare l'orientamento in fase di esecuzione chiude la mia app, tuttavia quando accedo alla mia app quindi vai a MainActivity e prova a cambiare l'orientamento, ricarica quell'attività e funziona bene. Ora la domanda è: perché? C'è un errore logico nel mio codice? Idk, ma ho provato a eseguire il debug dell'app diverse volte e non riesco a trovare nulla. Inoltre, non voglio riavviare la mia attività, perché non possiamo semplicemente adattare il rispettivo layout ogni volta che la configurazione cambia?
Ahsan,

10

La mia esperienza è che in realtà è meglio solo gestire correttamente i cambiamenti di orientamento invece di provare ad assumere un comportamento non predefinito.

Dovresti salvare l'immagine che è attualmente visualizzata onSaveInstanceState()e ripristinarla correttamente quando l'applicazione viene eseguita di onCreate()nuovo.


# 3 è una soluzione perfettamente valida. È lo strumento esatto creato per risolvere questo problema esatto. Perché dici che è il calzolaio?
Pacerier,

1
@Pacerier Basta leggere i documenti. "Nota: l'utilizzo android:configChangesdeve essere evitato e utilizzato solo come ultima risorsa. Leggere Gestione delle modifiche di runtime per ulteriori informazioni su come gestire correttamente un riavvio a causa di una modifica della configurazione."
Marc Plano-Lesay,

Potresti pubblicare un esempio di salvataggio e ripristino.
pollaris,

6

Questa soluzione è di gran lunga la migliore funzionante. Nel tuo file manifest aggiungi

<activity
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:name="your activity name"
    android:label="@string/app_name" 
    android:screenOrientation="landscape">
  </activity

E nella tua classe di attività aggiungi il seguente codice

@Override
public void onConfigurationChanged(Configuration newConfig) 
{
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //your code
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
  //your code

    }
}

4

aggiungi android:configChanges="keyboardHidden|orientation|screenSize"per tutti i tag attività app in manifest.


3

Aggiungi questo al tuo AndroidManifest.xml

<activity android:screenOrientation="landscape">

Voglio dire, c'è un tag attività, aggiungilo come un altro parametro. Nel caso in cui sia necessario l'orientamento verticale, cambiare orizzontale in verticale. Spero che questo ti aiuti.


non sto cercando di togliere la possibilità di ruotare lo schermo. non voglio che la mia app si ricarichi ... come ho già detto.
Jimmy D,

ps ... questo non funziona comunque. impone solo la visualizzazione dell'app in un certo orientamento. ruotando lo schermo si ricarica ancora l'attività
Jimmy D

3

Nel file più modificabile aggiungere ad ogni attività questo. Questo aiuterà

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

screenLayout ha funzionato per me, impedito l'aggiornamento durante il ridimensionamento dell'app per splitscreen su Android
Terren,

2

Tutte le risposte sopra non funzionano per me. Così, ho fissato menzionando la labelcon screenOrientationcome qui di seguito. Ora tutto bene

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




1

Come ha detto Pacerier,

android:configChanges="orientation|screenSize"


-1

Non so se sia la soluzione migliore, ma la descrivo qui:

Prima di tutto, hai bisogno del certificato con la tua classe L'applicazione della tua app è nel tuo manifest di questo:

<application
    android:name=".App"
    ...

Secondo, nella mia App di classe mi è piaciuto questo:

public class App extends Application {
    public static boolean isOrientationChanged = false;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onConfigurationChanged(@NotNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ||
                newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            isOrientationChanged = true;
        }
    }

}

In terzo luogo, è necessario impostare un flag su Modifica orientamento, nel mio caso, l'ho sempre impostato quando viene chiamata l'attività precedente all'interno della navigazione dell'app, quindi chiamata solo una volta quando viene creata l'attività successiva.

isOrientationChanged = false;

Quindi ogni volta che cambio l'orientamento del mio schermo in quel contesto, lo metto ogni volta che cambia questa impostazione, controlla se c'è un cambiamento nell'orientamento, in tal caso, lo convalida in base al valore di quella bandiera.

Fondamentalmente, ho dovuto usarlo ogni volta che ho fatto una richiesta di retrofit asincrona, che ha chiamato ogni momento che ha cambiato orientamento, bloccando costantemente l'applicazione:

if (!isOrientationChanged) {
    presenter.retrieveAddress(this, idClient, TYPE_ADDRESS);
}

Non so se sia la soluzione più elegante e bella, ma almeno qui è funzionale :)


-2

Aggiungi questo codice dopo il onCreatemetodo, nella tua attività contenente ilWebView

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

@Override
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);    
}

1
Come funzionerebbe? Non stai semplicemente dicendo qualcosa in modo esplicito al runtime, cosa altrimenti verrebbe fatto di default?
Danielson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.