2012-04-12 26 views
30

Sto diventando pazzo a capire qual è il modo migliore per gestire la rotazione dello schermo. Ho letto centinaia di domande/risposte qui, ma sono davvero confuso.Gestire la rotazione dello schermo senza perdere dati - Android

Come posso salvare i dati di myClass prima che l'attività venga ricreata in modo da poter conservare tutto per l'attività di ridisegno senza un'altra inizializzazione inutile?

Esiste un modo più pulito e migliore rispetto a parcelable?

Ho bisogno di gestire la rotazione perché voglio cambiare il layout in modalità orizzontale.

public class MtgoLifecounterActivity extends Activity { 

    MyClass myClass; 

    // Called when the activity is first created 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     If (?? first run...myClass == null ?) { 
      myClass = new MyClass(); 
     } else { 
      // do other stuff but I need myClass istance with all values. 
     } 
     // I want that this is called only first time. 
     // then in case of rotation of screen, i want to restore the other instance of myClass which 
     // is full of data. 
    } 
+0

utilizzare il materiale 'onConfigurationChanged', si veda: http://stackoverflow.com/questions/456211/activity-restart-on-rotation-android – Nanne

risposta

21

possono utilizzare il metodo di override onSaveInstanceState() e onRestoreInstanceState(). o di smettere di chiamare onCreate() sulla rotazione dello schermo è sufficiente aggiungere questa riga nel vostro XML manifest android:configChanges="keyboardHidden|orientation"

nota: la classe personalizzata deve implementa Parcelable esempio di seguito.

@Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putParcelable("obj", myClass); 
    } 

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState) { 
// TODO Auto-generated method stub 
super.onRestoreInstanceState(savedInstanceState); 
myClass=savedInstanceState.getParcelable("obj")); 
} 

public class MyParcelable implements Parcelable { 
    private int mData; 

public int describeContents() { 
    return 0; 
} 

/** save object in parcel */ 
public void writeToParcel(Parcel out, int flags) { 
    out.writeInt(mData); 
} 

public static final Parcelable.Creator<MyParcelable> CREATOR 
     = new Parcelable.Creator<MyParcelable>() { 
    public MyParcelable createFromParcel(Parcel in) { 
     return new MyParcelable(in); 
    } 

    public MyParcelable[] newArray(int size) { 
     return new MyParcelable[size]; 
    } 
}; 

/** recreate object from parcel */ 
private MyParcelable(Parcel in) { 
    mData = in.readInt(); 
} 


} 
+0

ma cosa devo fare suSaveInstanceState e onRestoreInstanceState? Implementa l'ordinabile? –

+0

sì necessario implementare parcelable. –

+0

pffff non esiste alcun metodo + facile? Ho bisogno di sapere la mia classe InstantAutoComplete che si estende da AutoCompleteTextView si estende da EditText implementa Filter.FilterListener .... Perdo 1 giorno per ottenere tutti i valori .... – delive

1

Se non si dispone di un bisogno per la vostra attività per essere riavviato solo impostare i configChanges attribuiscono sulla vostra attività nel AndroidManifest.xml a questo:

android:configChanges="keyboard|keyboardHidden|orientation" 

Questo dirà il sistema operativo che si si occuperà di gestire una rotazione e non riavvierà la tua attività. L'utilizzo di questo metodo rimuoverà la necessità di dover salvare qualsiasi tipo di stato.

+0

Questo non è il caso, Google dev sono sconsigliati questo Pratica in quanto ciò presuppone che il cambiamento di orientamento è l'unica ragione per cui l'attività può essere smaltita e ricreata quando, infatti, ci sono una serie di altri motivi per cui ciò può accadere. – BenjaminPaul

2

Ci sono due (buoni) modi a riguardo. Fai in modo che la tua classe implementa Parcelable e inseriscilo in un pacchetto in onSaveInstanceState() oppure, se è più complesso (ad esempio un AsyncTask), restituiscilo in onRetainNonConfigurationInstance().

Poi c'è anche il modo pigro in cui basta smettere di reagire alle modifiche di configurazione.

+0

questo sembra essere deprecato! Sì, è un oggetto abbastanza complesso - onRetainNonConfigurationInstance() –

+0

Yup, hanno deprecato 'onRetainNonConfigurationInstance()' ma non ha fornito un'alternativa, per quanto ho potuto dire. – dmon

+0

@dmon potrebbe utilizzare un frammento senza UI come alternativa: https://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean) –

27

In Attività Tag di Manifest si dovrebbe avere per citare

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

Se si utilizza Android 2.3 (livello di API 13) e soprattutto l'uso

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

Dovrebbe lavorare.

Esso funziona solo con attività tag e non con applicazione tag

+2

Il mio problema era nell'attributo screenSize, grazie a Prashant – bebosh

+1

Sempre benvenuti :) ... @bebosh – Cool7

11

Può essere questo è risolto già, ma solo per un piccolo aggiornamento per i nuovi membri che hanno bloccato su di esso, basta dare un'occhiata a Google Developer Site , Dal livello di API 13, è sufficiente aggiungere questo codice per manifestare:

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

quando una di queste configurazioni cambiano, SplashScreensActivity non si riavvia. Invece, SplashScreensActivity riceve una chiamata a onConfigurationChanged(). Questo metodo viene passato un oggetto Configuration che specifica la nuova configurazione del dispositivo. Leggendo i campi nella configurazione, è possibile determinare la nuova configurazione e apportare le modifiche appropriate aggiornando le risorse utilizzate nell'interfaccia.Quando viene chiamato questo metodo, l'oggetto Risorse della tua attività viene aggiornato per restituire le risorse in base alla nuova configurazione, in modo da poter ripristinare facilmente gli elementi dell'interfaccia utente senza che il sistema riavvii l'attività.

1

Il problema qui è che stai perdendo lo "stato" dell'App. In OOP, che cos'è uno stato? Le variabili! Esattamente! Quindi quando stai perdendo i dati delle tue variabili.

Ora ecco cosa puoi fare, Scopri le variabili che stanno perdendo i loro stati.

enter image description here

Quando si ruota il dispositivo, l'attività attuale viene completamente distrutta, cioè passa attraverso onSaveInstanceState()onPause() onStop() onDestroy() e una nuova attività viene creato completamente che attraversa onCreate() onStart()onRestoreInstanceState.

I due metodi in grassetto, onSaveInstanceState() salva l'istanza dell'attività presente che verrà distrutta. onRestoreInstanceState Questo metodo ripristina lo stato salvato dell'attività precedente. In questo modo non perderai il tuo precedente stato dell'app.

Ecco come si utilizzano questi metodi.

@Override 
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) { 
     super.onSaveInstanceState(outState, outPersistentState); 

     outState.putString("theWord", theWord); // Saving the Variable theWord 
     outState.putStringArrayList("fiveDefns", fiveDefns); // Saving the ArrayList fiveDefns 
    } 

    @Override 
    public void onRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState) { 
     super.onRestoreInstanceState(savedInstanceState, persistentState); 

     theWord = savedInstanceState.getString("theWord"); // Restoring theWord 
     fiveDefns = savedInstanceState.getStringArrayList("fiveDefns"); //Restoring fiveDefns 
    } 
Problemi correlati