Gestire con grazia il cambiamento dell'orientamento dello schermo durante l'avvio dell'attività

StackOverflow https://stackoverflow.com/questions/2434071

Domanda

Sto cercando di trovare un modo per gestire correttamente l'impostazione di un'attività in cui il suo orientamento è determinato dai dati nell'intento che lo ha lanciato. Questo è per un gioco in cui l'utente può scegliere i livelli, alcuni dei quali sono un orientamento al ritratto e alcuni sono orientamenti del paesaggio. Il problema che sto affrontando è quello setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) Non ha effetto fino a quando l'attività non è completamente carica. Questo è un problema per me perché faccio un po 'di caricamento ed elaborazione delle immagini durante l'avvio, cosa che vorrei dover fare solo una volta.

Attualmente, se l'utente ha scelto un livello di paesaggio:

  • L'attività inizia onCreate (), inadempiente al ritratto
  • scopre dall'analisi del suo intento di lancio che dovrebbe essere nell'orientamento del paesaggio
  • Continua a prescindere da OnResume (), caricando informazioni ed eseguendo altre attività di configurazione
  • A questo punto SetRequestorient si prende in giro, quindi l'applicazione passa tramite OnPause () a ondestroy ()
  • Quindi si avvia di nuovo da OnCreate () e corre su onResume () ripetendo la configurazione da prima

C'è un modo per evitarlo e non eseguire il carico due volte? Ad esempio, idealmente, l'attività saprebbe prima anche di OnCrea, se dovesse essere un paesaggio o un ritratto a seconda di alcune proprietà dell'intento di lancio, ma a meno che non mi sia perso qualcosa che non è possibile. Sono riuscito a hackerare un modo per evitare di ripetere il caricamento controllando a boolean Prima dei passaggi di caricamento che richiedono tempo, ma non sembra il modo giusto di farlo. Immagino di poter sovrascrivere onSaveInstanceState, ma ciò richiederebbe molta codifica aggiuntiva. C'è un modo semplice per fare questo?

Grazie!


Soluzione:

Secondo la risposta di Daniel, questo è stato in realtà abbastanza facile da risolvere. Avevo solo bisogno di apportare alcune piccole modifiche. Nella mia attività di "menu", in cui il giocatore avrebbe scelto quale livello giocare, dovevo solo aggiungere un controllo If/Else per scegliere quale classe sarebbe stata avviata dal mio intento. Ciò è stato fatto con un semplice INT che rappresenta il ritratto o il paesaggio, determinato quando il giocatore ha selezionato un livello. Ho quindi creato una seconda classe che estende la mia classe "gamelogic"; Questa è la classe che conteneva la maggior parte del codice per il gioco stesso, piuttosto che i menu, le istruzioni, ecc.

public class GameLandscape extends GameLogic{
}

Letteralmente così semplice e completamente vuoto. In questo modo ha ereditato tutto il codice dalla mia attività precedente in cui l'avevo già codificato per gestire le cose in modo diverso a seconda dell'orientamento. Infine, ho dovuto solo aggiungere una linea al manifest affermando che Gamelandscape avrebbe sempre funzionato nel paesaggio e Gamelogic avrebbe sempre funzionato nel ritratto.

Quindi un semplice problema davvero.

È stato utile?

Soluzione

Potresti fare due attività - una per i livelli di ritratto, l'altro per i livelli del paesaggio - e quindi impostare l'orientamento dell'attività in AndroidManifest.xml, usando il android:screenOrientation attributo. Non dovrai nemmeno duplicare il codice se usi l'eredità; Usa la tua attività attuale come attività di base e crea semplicemente le attività del paesaggio/ritratto come sottoclassi di tale attività.

Penso che una soluzione migliore sarebbe per l'intenzione di aprire l'attività corretta di questi due, anche se se devi essere inserito tutto tramite un'analisi extra di intento, potresti inoltrare tutti i livelli a una terza attività che non fa altro che analizzare l'intento e Quindi inoltrano all'attività corretta.

Altri suggerimenti

Potresti anche sovrascrivere onRetainNonConfigurationInstance(). Questo ti consente di archiviare temporaneamente un elemento che puoi recuperare chiamando getLastNonConfigurationInstance(). In questo modo puoi caricare tutte le cose di cui hai bisogno e nel tuo onRetainNonConfigurationInstance() Metodo È possibile salvare tutto in una struttura dei dati e restituirlo. Il tuo onCreate() Puoi chiamare getLastNonConfigurationInstance() E se ciò restituisce il carico nullo, carichi tutte le tue cose, se restituisce qualcosa, allora lo hai caricato. Ecco un rapido esempio:

public class MyActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        DataStructure myData = (DataStructure)getLastNonConfigurationInstance();
        if(myData == null)
        {
            // Load everything in
        }
        else
        {
            // Unpack myData
        }
    }

    @Override
    public Object onRetainNonConfigurationInstance()
    {
        DataStructure myData = new DataStructure();
        // Put everything in to myData
        return myData;
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top