2012-09-19 21 views
48

Tengo un ArrayList con objetos personalizados que me gustaría poder guardar y restaurar en una pantalla rotada.¿Cómo se puede girar ArrayList personalizado en la pantalla de Android?

sé que esto se puede hacer con onSaveInstanceState y onRestoreInstanceState si tuviera que hacer el ArrayList su propia clase, que implementa ya sea Parcelable o Serializable ... Pero hay una manera de hacer esto sin crear otra clase?

Respuesta

81

No necesita crear una nueva clase para pasar una lista de arreglos de sus objetos personalizados. Simplemente debe implementar la clase Parcelable para su objeto y usar Bundle#putParcelableArrayList() en onSaveInstanceState() y onRestoreInstanceState(). Este método almacenará una ArrayList de Parcelables por sí mismo.


Debido a que el tema de Parcelables (y Serializables y Paquetes) a veces hace que me duela la cabeza, aquí es un ejemplo básico de un ArrayList que contiene objetos personalizados parcelable almacenados en un paquete. (Esta pasta se corta & ejecutable, sin la disposición necesaria.)

Ejecución parcelable

public class MyObject implements Parcelable { 
    String color; 
    String number; 

    public MyObject(String number, String color) { 
     this.color = color; 
     this.number = number; 
    } 

    private MyObject(Parcel in) { 
     color = in.readString(); 
     number = in.readString(); 
    } 

    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public String toString() { 
     return number + ": " + color; 
    } 

    public void writeToParcel(Parcel out, int flags) { 
     out.writeString(color); 
     out.writeString(number); 
    } 

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

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

Unidos

public class Example extends ListActivity { 
    ArrayList<MyObject> list; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     if(savedInstanceState == null || !savedInstanceState.containsKey("key")) { 
      String[] colors = {"black", "red", "orange", "cyan", "green", "yellow", "blue", "purple", "magenta", "white"}; 
      String[] numbers = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"}; 

      list = new ArrayList<MyObject>(); 
      for(int i = 0; i < numbers.length; i++) 
       list.add(new MyObject(numbers[i], colors[i])); 
     } 
     else { 
      list = savedInstanceState.getParcelableArrayList("key"); 
     } 

     setListAdapter(new ArrayAdapter<MyObject>(this, android.R.layout.simple_list_item_1, list)); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     outState.putParcelableArrayList("key", list); 
     super.onSaveInstanceState(outState); 
    } 
} 
+1

Gracias! Sin embargo, estoy perdido en el 'MyObject privado (Parcela) { color = in.readString(); number = in.readString(); } 'bit ... Eso es fácil para Strings, pero ¿cómo leo mi lista de arrays personalizada? 'in.readArrayList (MyObject.class.getClassLoader())' me da un error. – Kalina

+1

Hmm, en su pregunta, preguntó acerca de "una lista de matrices con objetos personalizados" que implica 'ArrayList ', que esta respuesta maneja en 'Parcelable.Creator'; Sin embargo, su comentario solo preguntaba "¿cómo leo mi lista de arrays personalizada?", lo que implica 'MyArrayList'. ¿Qué clase estás tratando de extender? (Perdón por ser técnico, pero quiero darte la mejor respuesta lo más rápido posible). – Sam

+0

Lo siento, me refiero a ArrayList Kalina

3

Guardar/Restaurar Puede utilizar onRetainNonConfigurationInstance(). Le permite guardar cualquier objeto antes de un cambio de configuración y restaurarlo después con getLastNonConfigurationInstanceState().

Dentro de la actividad:

@Override 
    public Object onRetainNonConfigurationInstance() { 
     return myArrayList; 
    } 

Dentro onCreate():

try{ 
     ArrayList myArrayList = (ArrayList)getLastNonConfigurationInstance(); 
    } catch(NullPointerException e) {} 

manejar los cambios de tiempo de ejecución: http://developer.android.com/guide/topics/resources/runtime-changes.html Documentación: http://developer.android.com/reference/android/app/Activity.html#onRetainNonConfigurationInstance%28%29

+0

¡Guau, nunca supe de esa función! Súper simple y exactamente lo que necesitaba ... Sin embargo, veo que está en desuso ... – Kalina

+0

Desafortunadamente, pero todavía funciona y no hay otra manera fácil de hacerlo. La respuesta de Sam es la única otra forma que he encontrado, pero es mucho más difícil de implementar. – Techwolf

+3

Si está utilizando Fragmentos, puede usar 'Fragment.setRetainInstance (true)' en su lugar, que es la versión más nueva de esto (pero solo funciona con Fragmentos). Documentación: http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean) – Techwolf

-2

sí, se puede guardar su objeto compuesto en las preferencias compartidas. Digamos:

Student mStudentObject = new Student(); 
    SharedPreferences appSharedPrefs = PreferenceManager 
     .getDefaultSharedPreferences(this.getApplicationContext()); 
     Editor prefsEditor = appSharedPrefs.edit(); 
     Gson gson = new Gson(); 
     String json = gson.toJson(mStudentObject); 
     prefsEditor.putString("MyObject", json); 
     prefsEditor.commit(); 

y ahora puede recuperar su objeto como:

 SharedPreferences appSharedPrefs = PreferenceManager 
    .getDefaultSharedPreferences(this.getApplicationContext()); 
    Editor prefsEditor = appSharedPrefs.edit(); 
    Gson gson = new Gson(); 
    String json = appSharedPrefs.getString("MyObject", ""); 
    Student mStudentObject = gson.fromJson(json, Student.class); 
+1

Mala idea para hacer esto, dependiendo de el tamaño de la lista que se guarda. SharedPreferences es un archivo XML, no está diseñado para el almacenamiento de grandes conjuntos de datos. – mwieczorek

Cuestiones relacionadas