Rotación de la pantalla en Android

Girar tu dispositivo ya no será un problema

En Android, los dispositivos móbles permite rotar la pantalla y ofrecer un layout distinto según la orientación. La rotación de la pantalla conlleva tener que restaurar las vistas y campos de nuestras activities. Si queremos implementar la rotació utilizando layouts distintos para cada orientación, debemos seguir los siguientes pasos:

  1. Indicar el comportamiento ante la rotación de pantalla en el AndroidManifest.xml
  2. Crear carpetas y layouts para cada orientación.
  3. Sobrescribir el método onSavedInstanceState() para guardar el valor de los campos de la clase antes de rotar.
  4. Crear un método para restaurar el valor de los campos tras el giro de la pantalla.

Esta es la pagina oficial de Android que explica cómo realizar el mismo procedimiento que vaos a explicar a continuación: https://developer.android.com/training/basics/activity-lifecycle/recreating.html.

1. Indicar el comportamiento ante la rotación de la pantalla

La orientación de cada pantalla de nuestra aplicación viene definida en el archivo AndroidManifest.xml. En el atributo screenOrientation podemos definir el modo en que se mostrará la pantalla:

  • ninguna: si no especificamos el atributo, la pantalla girará al girar el dispositivo.
  • portrait: solo vertical.
  • landscape: solo horizontal.
  • locked: la pantalla se mostrará en la orientación en que se encuentre en ese momento el dispositivo y no cambiará al girar.

Por lo tanto, si queremos que nuestra pantalla gire, no debemos indicar ninguno. Existen otros modos además de estos.

2. Crear carpetas y layouts para cada orientación

Carpetas

Para que Android sepa qué layout debe aplicar para cada orientación, tenemos que crear carpetas con calificadores de orientación. En la carpeta res de nuestra aplicación crearemos una carpeta que se llame layout-land (de landscape) y en ella irán los layouts para la orientación horizonal. Cuando el dispositivo esté en horizontal, Android tomará los layouts de esta carpeta, y si no hay un layout para la pantalla actual, lo tomará de la carpeta layout.

Podemos igualmente renombrar la carpeta layout por layout-port para ser más descriptivos, pero no es necesario, ya que solo hay dos horientaciones y si no es una, es la otra.

Layouts

Por cada pantalla en la que queramos implementar la rotación debemos crear un layout horizontal que se llame igual que el de la orientación vertical y asegurarnos de que las vistas comunes a ambos tienen los mismos id para que se restauren automáticamente tras rotar.

3. Sobrescribir el método onSavedInstanceState(Bundle outState)

Por defecto, cuando se produce la rotación, la activity se encarga de conservar automáticamente el estado de aquellas vistas en su layout que tengan id (de un CheckBox guarda si está marcado o no, de un EditText guarda su texto…). Para ello guardará pares clave-valor en el bundle outState del método onSavedInstanceState(Bundle outState) utilizando como clave el id. Y después, restaurará automáticamente el estado de estas vistas en el método onRestoreInstanceState(Bundle savedInstanceState).

Es decir, las vistas se restauran solas. Lo que no se restaura es el valor de los campos de la clase, como por ejemplo el valor de private boolean activado o de private Integer resultado. Estos son los campos que debemos encargarnos de almacenar si nos interesa.

Para ello sobrescribiremos el método onSavedIntanceState(Bundle outState) para añadir al bundle outState donde Android guarda el estado de las vistas todo aquello que deseemos conservar tras la rotación. Este bundle será recibido tanto en el método onCreate(Bundle savedInstanceState) al recrear la activity, como en el método onRestoreInstanceState(Bundle savedInstanceState).

4. ¿Dónde restaurar?

Cuando se produce la rotación de la pantalla, la activity es destruida y creada de nuevo, por lo que tendremos dos ocasiones para restaurar los campos: en el onCreate() y en el onRestoreInstanceState(). Suele convenir hacerlo en el onCreate(), ya que es en este método donde definimos la lógica de las vistas, y tal vez nos interese modificarla según el valor de los campos almacenados.

El método onCreate(Bundle savedInstanceState) recibe un bundle llamado savedInstanceState, que es el mismo que en el que hemos almacenado aquellos valores que queríamos restaurar en el onSavedInstanceState(Bundle outState). Con él ya podemos restaurar los campos de la clase.

Por otro lado, el método onRestoreInstanceState(Bundle saveInstanceState) es el método que automáticamente restaurará el estado de las vistas de nuestro layout que tengan el mismo id que en el layout de la orientación anterior. Este método se ejecuta en algún momento entre el onStart() y onPostCreate(). Es decir, que si decidimos sobrescribirlo y restaurar los campos aquí, debemos tener en cuenta que ya se habrá ejecutado todo el código del onCreate().

5. Ejemplo

En este ejemplo, restauraremos los campos en el onCreate(). En esta clase hemos creado el método restaurarCampos(), al cual hemos de pasarle el savedInstanceState y dentro escribimos la lógica de restauración. Esteos son nuestro layout y nuestra MainActivity.

Pantalla inicial con los campos vacíos

activity_main.xml

MainActivity.class

En este caso, la clase tiene dos campos que no son vistas: pulsado y textoIntroducido (los estáticos no es necesario almacenarlos), por lo que, al girar la pantalla, en el onSavedInstanceState() guardaremos sus valores en el bundle. El segundo parámetro que reciben los métodos get~() de la clase Bundle es el valor que se devolverá en caso de no encontrar el par clave-valor para la clave solicitada.

Luego, la activity será destruida y reconstruida y esto es lo que pasará:

  1. Se llamará al onCreate() y dentro de este, al método setContentView(), el cual volverá a asignar nuestro layout en su estado primitivo a la activity. Como el TextView tvText tiene visibilidad gone por defecto, este se ocultará sin importar que antes de rotar estuviera visible.
  2. Después se llamará a restaurarCampos() y, si hemos pulsado el botón, se recuperará el booleano pulsado y el String textoIntroducido.
  3. Por último se ejecutará el resto del método onCreate(): se comprobará si el valor de pulsado es true, en cuyo caso, se mostrará el TextView y se le asignará el textoIntroducido.
  4. Después se llamará automáticamente al onRestoreSavedInstance() el cual restaurará el contenido anterior del EditText etTexto.

Así que como puedes ver, era necesario restaurar los campos en el onCreate(), o de lo contrario, el TextView no se habría vuelto a mostrar con su texto tras la rotación.

1.
Pantalla con datos introducidos

Introducimos datos y pulsamos el botón

2.
Pantalla con las vistas conservadas

Tras la rotación, se conservan los campos y las vistas

Una pequeña observación además de lo ya comentado. Por defecto, el contenido de un TextView no es conservado automáticamente. Para que sea conservado, debemos asignarle la propiedad android:freezesText="true" en el layout. Se conservará al rotar incluso por encima del valor primitivo asignado en el layout.

0 Comentarios

Contesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

©2017 Codictados Comunidad libre para el aprendizaje de codigo Online

o

Inicia Sesión con tu Usuario y Contraseña

o    

¿Olvidó sus datos?