31 comentarios el “Mantener los datos cuando rotemos la pantalla en Android

    • Buenos días dani_91.

      Si puedes, si te fijas es como cuando pasas variables de una Activity a otra. Lo único que hay que tener en cuenta es que va por clave-valor o key-value, como lo quieras llamar.

      Te he hecho un ejemplo básico en el que guardo el texto de 4 EditText, que aunque se puede simplificar, pero se vé mejor:

      public class MainActivity extends Activity {
      	private EditText et1, et2, et3, et4;
      
      	@Override
      	protected void onCreate(Bundle savedInstanceState) {
      		super.onCreate(savedInstanceState);
      		setContentView(R.layout.activity_main);
      		
      		et1 = (EditText)findViewById(R.id.editText1);
      		et2 = (EditText)findViewById(R.id.editText2);
      		et3 = (EditText)findViewById(R.id.editText3);
      		et4 = (EditText)findViewById(R.id.editText4);
      	}
      
      	@Override
      	protected void onSaveInstanceState(Bundle outState) {
      		// TODO Auto-generated method stub
      		super.onSaveInstanceState(outState);
      		String edit1 = et1.getText().toString(); 
      		String edit2 = et2.getText().toString();
      		String edit3 = et3.getText().toString();
      		String edit4 = et4.getText().toString();
      		
      		outState.putString("STRING1", edit1);
      		outState.putString("STRING2", edit2);
      		outState.putString("STRING3", edit3);
      		outState.putString("STRING4", edit4);
      		
      	}
      
      	@Override
      	protected void onRestoreInstanceState(Bundle savedInstanceState) {
      		// TODO Auto-generated method stub
      		super.onRestoreInstanceState(savedInstanceState);
      		String edit1 = savedInstanceState.getString("STRING1");
      		String edit2 = savedInstanceState.getString("STRING2");
      		String edit3 = savedInstanceState.getString("STRING3");
      		String edit4 = savedInstanceState.getString("STRING4");
      		
      		et1.setText(edit1);
      		et2.setText(edit2);
      		et3.setText(edit3);
      		et4.setText(edit4);
      	}
      
      }
      

      Si por otro lado, quieres almacenar un objeto de alguna clase que tengas, yo el único modo que he probado es implementando la interface Parcelable en la clase que quiero almacenar, aunque seguramente haya otros.

      Saludos!!

    • Puedes hacerlo con la clase Bitmap, ya que implementa la interface Parcelable, por tanto solo deberías hacer:

      outState.putParcelable("IMAGEN", bitmap);
      

      Donde “IMAGEN” es la key, y bitmap la referencia al objeto.

      Saludos!!!

      • la imagen la tengo en un ImageView com ola paso a bitmap

        Bitmap img = pbImagen.get??????? la paso a bitmap

        outState.putParcelableArr(“DESC”, img); la guardo

      • muy buenas, yo estoy cogiendo de mi imageview la imagen que previamente me descargo, la convierto a bitmap:
        Bitmap bitmap = ((BitmapDrawable) MiImageView.getDrawable()).getBitmap();
        outState.putParcelable(“IMAGEN”, bitmap);

        en el restore:
        imagencache = savedInstanceState.getParcelable(“IMAGEN”);

        Y luego para asignarla tengo problemas(no me funciona) he probado:

        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra(“BitmapImage”, imagencache);
        Bitmap bitmap = (Bitmap) intent.getParcelableExtra(“BitmapImage”);
        // Deserialize Parcelable and cast to Bitmap first:
        m_imageView.setImageBitmap(bitmap);
        La verdad que no se como hacer, cuando giro el telefono vuelve a cargar una imagen que se baja de mi servidor. Tarda cuestion de segundos pero me gustaria no tener que volver a bajarla(y consumir datos alegremente, aunque son de pocos kbytes).

        Bueno a ver si doy con la solucion! Un saludo

      • Buenas inachomsky,

        Esta fracción de código:

        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra(“BitmapImage”, imagencache);
        

        La usaría para pasar un Bitmap de una Activity a otra, pero no para mantener la imagen cuando rotemos la pantalla.

        Cuando se rota la pantalla, se hace comprobando en el método onCreate si el objeto Bundle es null o no.

        Si es null, quiere decir que tu imagen no se ha guardado, y si no es null, puedes extraer entonces el Bitmap con la fracción de código:

        imagencache = savedInstanceState.getParcelable(AQUÏ_LA_KEY);
        

        Espero que te sea de ayuda y por cualquier duda aquí estoy.

        Saludos!

  1. funcionaria con notificaciones de la barra de estado???, yo tengo un reproductor streaming en segundo plano pero cuando lo mando llamar desde la barra de notificaciones deja de funcionar, talvez es porque no esta guardando la url de trasmicion (porque la tengo como variable)

  2. Gracias por la rapida respuesta!
    Es lo que pensaba( no entendia muy bien el codigo cogi esa parte de una web), creia que mi problema podia ser la manera en que cojo la imagen(ya que la descargo, la situo en el imageview, y luego la guardo sacandola del imageview, no se aun como funciona android con las descargas y si esto esta bien hecho)

    Ahora tengo esto:
    @Override
    protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    //guardamos la informacion relevante
    Bitmap bitmap = ((BitmapDrawable) m_imageView.getDrawable()).getBitmap();
    outState.putParcelable(“IMAGEN”, bitmap);
    }
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState)
    {
    super.onRestoreInstanceState(savedInstanceState);
    imagencache = savedInstanceState.getParcelable(“IMAGEN”);
    }

    Y creo que el problema esta aqui:
    en el main creo la variable
    private Parseable imagencache;

    (en el on create)

    la asigno asi:

    Bitmap bitmap = (Bitmap) savedInstanceState.getParcelable(“imagecache”);
    // Deserialize Parcelable and cast to Bitmap first:
    m_imageView.setImageBitmap(bitmap);

    Creo que estoy fallando al asignar la imagen en el m_imageView, o tal vez en el tipo de variable “imagencache”.
    Bueno, muchisimas gracias por la ayuda un detallazo!.

    • Buenas Enmanuel,

      Efectivamente se puede pasar un ArrayList, y una de las soluciones mas fáciles es que el tipo de dato que maneje el ArrayList implemente la Interface Serializable o Parcelable, ya que así en un objeto de la clase Intent puedes usar los métodos putParcelableArrayListExtra(name, value) en el caso de que la clase del objeto implemente esta Interface (lo cuál es basatnte fácil :)). Si por otro casual quieres pasar un ArrayList de String, puedes usar el método putStringArrayListExtra(name, value).

      Por ponerte un ejemplo, si tienes una clase Item y esta clase implementa la Interface Parcelable, al hacer un ArrayList ya podrás pasarlo a la siguiente Activity.

      Espero que te sea de ayuda Enmanuel,

      Saludos!

  3. buenas tardes
    tengo una app en android en la qe ocupo que al rotar la pantalla esta conserve todos los datos, algunos de los datos los guardo en SQLite, sharedPreferences, etc, pero tengo adapters personalizados con los cuales lleno algunas listview o combobox para seleccionar una opcion y estos no se de que manera puedo almacenarlos, ademas de qe mi app consta de varias activityes y si roto la pantalla enalguna de estas las demas tamb se ven afectadas ya que cuando regreso a ellas los datos se borran de pantalla
    espero puedas ayudarme
    saludos

      • Buenos días beto,

        Los adapters personalizados no son más que adapter que se adaptan a una clase que tengas creada, por tanto, si esa clase implementa la interface Parcelable puedes guardar esos objetos en memoria para cuando hay rotación, cargar de nuevo el Arrayilst donde tengas almacenados esos objetos, y ya luego crear de nuevo el Adapter para cargar de nuevo todo tal como estaba.

        Las instancias de SQLite deberías hacer que implementen el patrón Singleton el cual logra que solo puedas tener una instancia, por tanto, estés en la Activity que estés, siempre tendrás la misma instancia y podrás trabajar con ello.

        Espero que te sirva de guia 😉

        Saludos!

  4. Hola David!
    He intentado guardar la posicion de un item seleccionado en unos spinner pero no ha funcionado. El código es este.

    @Override
    protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    outState.putInt(“proyecto”, proy.getSelectedItemPosition());
    outState.putInt(“situacion”, sit.getSelectedItemPosition());
    outState.putInt(“tipoi”, inc.getSelectedItemPosition());
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState){
    super.onRestoreInstanceState(savedInstanceState);
    proy.setSelection(savedInstanceState.getInt(“proyecto”));
    sit.setSelection(savedInstanceState.getInt(“situacion”));
    inc.setSelection(savedInstanceState.getInt(“tipoi”));

    }

    Espero puedas ayudarme.

    • Buenas tardes Enmanuel,

      El código a primera vista está bien, por lo que el error puede darse en el momento en el que se cargan los Spinner inicialmente, porque como habrás comprobado el método onCreate se inicia antes que el método onRestoreInstanceState, por tanto sería comprobar si para cuando llega a onRestoreInstanceState ya hay algo en esos Spinner.

      Por otro lado, no te funciona porque te da algún tipo de error?

      Saludos!

  5. No da ningún error. Lo único que pasa es que, al rotar la pantalla, el elemento seleccionado es el primero, es decir, la posición 0.

    • Buenas Enmanuel,

      Por lo que puedo ver también, tienes 3 Spinner, ¿Son secuenciales?, es decir, eligiendo algo en el 1º se carga algo del 2º, y según el 2º se carga el 3º?, si es así puede ser que solo necesitaras guardar el estado del 1º. Es una suposición, pero en principio tu código es correcto :S

      Otra cosa que puedes probar es recuperar esos valores al final del onCreate, haciendo la comprobación de comprobar si el objeto savedInstanceState es null o no.

      Saludos!

      • No son secuenciales.
        Sl final del onCreate é colocado esto “Log.i(“spinner”, proy.getSelectedItem().toString());” y como tu dices, me manda un error de nullPointerException.
        ¿Qué puedo hacer?

      • Buenas Enmanuel,

        Has probado a sacar por el Log el valor del objeto Bundle?.

        Si te dá NullPointerException es porque parece ser que no tiene nada, es mas, el spinner no está instanciado y es null, revisa biene l orden en el que se ejecuta todo y pon salidas en el Log antes y después de las operaciones que crees que fallan, eso te ayudará a saber mas o menos exactamente hasta donde llega y localizar el error.

        Espero sirva de ayuda 😉

        Saludos!

  6. Hola Enmanuel, tengo exactamente el mismo problema tuyo, tengo un Spinner que se carga de datos que vienen de un JSON en un servidor externo. Justamente dichos datos son cargados en el método onStart(), el problema surge cuando selecciono un ítem de mi Spinner, automáticamente es visible el ítem que seleccioné, pero cuando volteo el dispositivo, este ítem seleccionado deja de ser visible, y el primer ítem de mi lista vuelve a posicionarse en el primer lugar, como si no hubiese seleccionado el item de mi Spinner. Todavía no doy la solución, por favor, si llegas a la solución mucho antes que yo, notificamelo. Gracias

  7. Hola David, yo estoy intentando hacer lo mismo pero con una libreria para un libro para dispositivo movil, esta libreria trabaja con un setadapter, y al rotar el dispositivo necesito que se mantenga en la pagina en donde estaba antes de rotar el dispositivo y obviamente tambien mantener su contenido, intente hacerlo con el onConfigurationChanged y logro el efecto deseado, pero lo malo es que al dar vuelta a la otra pagina como que se desconfigura todo al principio, se ve mal y cuesta girar de pagina y al girar 2 paginas recien se adapta. Espero que puedas ayudarme en algo y ojala haya explicado bien mi problema,

    Saludos.

  8. Hola, tengo el problema de que al rotar pierdo los datos de un array, e intentado adaptar este ejemplo que comentavas pero no me esta saliendo tengo esto para guardar el array.

    @Override
    protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    outState.putParcelable(“ARRAY”, (Parcelable) listaContactos);

    setContentView(R.layout.activity_main);

    //Obtenemos una referencia a los controles de la interfaz
    InpNombre = (EditText) findViewById (R.id.InputName);
    botonADD = (Button)findViewById(R.id.botonADD);
    listView = (ListView) findViewById(R.id.listView);
    listaContactos = new ArrayList();
    //(EntradaLista, es una clase para tratar los datos a insertar la lista junto con la clase adaptador)

    … mi codigo …
    }

    y este para recuperar.

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

    listaContactos = savedInstanceState.getParcelable(“ARRAY”);
    adapter.notifyDataSetChanged();
    }

    el primer problema es que al arrancar la aplicacion muchas veces no aparece mi layout de botones con la lista. el segundo es que al rotar me da un error.

    que me esta fallando.

  9. hola amigo, tengo un problema con el codigo, pues yo lo implemente tu ejemplo cuando ago cambui de activity y el problema es el siguiente:

    outState.putString(“STRING1”, etnombrecomandante); -> me indica que cambie el putString
    outState.putString(“STRING2”, etcorporacion);
    outState.putString(“STRING3”, etnarracion);

    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onRestoreInstanceState(savedInstanceState);
    String Stretnombrecomandante = savedInstanceState.getString(“STRING1”);
    String Stretcorporacion = savedInstanceState.getString(“STRING2”);
    String Stretnarracion = savedInstanceState.getString(“STRING3”);

    etnombrecomandante.setText(etnombrecomandante); —>me indica error en el settext
    etcorporacion.setText(etcorporacion);
    etnarracion.setText(etnarracion);

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s