No recargue la aplicación cuando cambie la orientación

152

Simplemente no necesito nada para cambiar cuando se gira la pantalla. Mi aplicación muestra una imagen aleatoria cuando se carga por primera vez y al girar el dispositivo no debería seleccionar otra imagen aleatoria. ¿Cómo puedo (simplemente) hacer que este comportamiento se detenga?

Jimmy D
fuente
1
También es posible bloquear (y posiblemente desbloquear) la orientación de la pantalla desde el código. Simplemente llame Screen.lockOrientation(this)desde github.com/delight-im/Android-BaseLib/blob/master/Source/src/im/… para esto. Permite desbloquear lo que no hace el manifiesto.
graznido
@Escobar Ceaser ¿Cuál es la solución adecuada para esta pregunta? Incluso tengo el mismo requisito.
Prabs
Me gustaría hacer esto mediante programación en código.
pollaris

Respuestas:

249

Generalmente hay tres formas de hacer esto:

  1. Como sugieren algunas de las respuestas, puede distinguir los casos en que su actividad se crea por primera vez y se restaura savedInstanceState. Esto se hace anulando onSaveInstanceStatey verificando el parámetro de onCreate.

  2. Puede bloquear la actividad en una orientación agregando android:screenOrientation="portrait"(o "landscape") <activity>en su manifiesto.

  3. Podrías decirle al sistema que querías manejar los cambios de pantalla por ti mismo especificando android:configChanges="orientation|screenSize"en la <activity>etiqueta. De esta manera, la actividad no se volverá a crear, sino que recibirá una devolución de llamada (que puede ignorar ya que no es útil para usted).

Personalmente iría con (3). Por supuesto, si está bien bloquear la aplicación en una de las orientaciones, también puede ir con (2).

Xion
fuente
13
Entonces, para el # 3, ¿estás diciendo que todo lo que tengo que hacer es agregar esa línea a mi manifiesto? Porque no funciona
Jimmy D
2
# 3 Por favor verifique en stackoverflow.com/questions/456211/…
Yeo
16
@EscobarCeaser, para Android 3.2 y superior, necesitaandroid:configChanges="orientation|screenSize"
Pacerier
9
android:configChanges="orientation|screenSize"funciona para mi. Gracias @Pacerier
Don
1
por favor, actualice su caso de respuesta # 3 con android:configChanges="orientation|screenSize"valor para API> = 13, ¡porque muchas personas ven su respuesta como principal!
radistao
215

La respuesta de Xion fue cercana, pero # 3 ( android:configChanes="orientation") no funcionará a menos que la aplicación tenga un nivel de API de 12 o inferior.

En el nivel 13 de API o superior, el tamaño de la pantalla cambia cuando cambia la orientación, por lo que esto todavía hace que la actividad se destruya y se inicie cuando cambia la orientación.

Simplemente agregue el atributo "screenSize" como hice a continuación:

<activity
    android:name=".YourActivityName"
    android:configChanges="orientation|screenSize">
</activity>

Ahora, cuando cambia la orientación (y el tamaño de la pantalla cambia), la actividad mantiene su estado y onConfigurationChanged() se llama. Esto mantendrá lo que esté en la pantalla (es decir, página web en una vista web) cuando cambie la orientación.

Aprendí esto de este sitio: http://developer.android.com/guide/topics/manifest/activity-element.html

Además, aparentemente esta es una mala práctica, así que lea el siguiente enlace sobre Manejo de cambios en tiempo de ejecución:

http://developer.android.com/guide/topics/resources/runtime-changes.html

corbin
fuente
2
Gracias ... su trabajo después de agregar "screenSize" con "orientación"
Pratik Butani
Funciona en Samsung Galaxy Nexus android 4.2.1! android:configChanges="orientation|screenSize"
Vincent Ducastel
Asombroso. He estado trabajando a través del código durante tantas horas para resolver un problema que tuve con la recarga de la actividad y un video desde el principio. ¡Y aquí estaba la solución! ++++ 1
Mathias Asberg
66
¿Mala práctica? Pfft, las personas de la vida real tienen plazos y si funciona, funciona;)
Kacy
Si esta es una mala práctica, ¿por qué recibió tantos votos positivos?
Sharp Edge
26

Solo tiene que ir al AndroidManifest.xmlinterior o en las etiquetas de sus actividades, debe escribir esta línea de código como alguien allí dijo:

android:configChanges="orientation|screenSize"

Entonces, tendrás algo como esto:

<activity android:name="ActivityMenu"
android:configChanges="orientation|screenSize">
</activity>

¡Espero que funcione!

Josue Rocha
fuente
no está cargando mi diseño de diseño de tierra. :( no funcionó para mí
piyush poriya
16
<activity android:name="com.example.abc" 
 android:configChanges="orientation|screenSize"></activity>

Solo agrega android:configChanges="orientation|screenSize" pestaña de actividad del archivo de manifiesto.

Por lo tanto, la actividad no se reiniciará cuando cambie la orientación.

Aiyaz Parmar
fuente
Esta funcionando. Pero cuando estoy usando un diseño separado para cada orientación layout.xml y layout-land.xml. aplica el diseño del paisaje para ambas orientaciones. Si uso solo "orientación", está dando lo que espero pero volviendo a cargar. ¿Podrías ayudarme en esto?
Karthikeyan Ve
1
@KarthikeyanVe Ese es el problema cuando intentas hacer trampa. Usted tiene que reiniciar su actividad al diseño de cambio. Siga adelante y simplemente use la solución real, que está usando onSaveInstanceState()y onCreate().
Marc Plano-Lesay
@ MarcPlano-Lesay y ¿cómo se supone que debo hacer eso?
Ahsan
@Weaboo, la solución real está vinculada en la pregunta: developer.android.com/guide/topics/resources/…
Marc Plano-Lesay
@ MarcPlano-Lesay Tengo un diseño separado para el modo vertical y horizontal, si abro mi aplicación en modo horizontal o vertical funciona bien, pero cada vez que trato de cambiar la orientación en tiempo de ejecución cierra mi aplicación, sin embargo, cuando inicio sesión en mi aplicación y luego navegue a MainActivity e intente cambiar la orientación, recarga esa actividad y funciona bien. Ahora la pregunta es ¿porque? ¿Hay un error lógico en mi código? Idk, pero he intentado depurar la aplicación varias veces y no puedo encontrar nada. Además, no quiero reiniciar mi actividad, ¿por qué no podemos adaptar el diseño respectivo cada vez que cambia la configuración?
Ahsan
10

Según mi experiencia, en realidad es mejor tratar los cambios de orientación correctamente en lugar de tratar de calzar un comportamiento no predeterminado.

Debe guardar la imagen que se muestra actualmente onSaveInstanceState()y restaurarla correctamente cuando la aplicación se ejecute onCreate()nuevamente.

dmon
fuente
# 3 es una solución perfectamente válida. Es la herramienta exacta hecha para resolver este problema exacto. ¿Por qué dices que se trata de calzar zapatos?
Pacerier
1
@Pacerier Acabo de leer los documentos. "Nota: El uso android:configChangesdebe evitarse y usarse solo como último recurso. Lea Manejo de cambios en el tiempo de ejecución para obtener más información sobre cómo manejar adecuadamente un reinicio debido a un cambio de configuración".
Marc Plano-Lesay
¿Podría publicar un ejemplo guardando y restaurando?
pollaris
6

Esta solución es, con mucho, la mejor que funciona. En su archivo de manifiesto agregue

<activity
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:name="your activity name"
    android:label="@string/app_name" 
    android:screenOrientation="landscape">
  </activity

Y en su clase de actividad agregue el siguiente código

@Override
public void onConfigurationChanged(Configuration newConfig) 
{
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //your code
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
  //your code

    }
}
Un raj
fuente
4

agregue android:configChanges="keyboardHidden|orientation|screenSize"para todas las etiquetas de actividades de la aplicación en manifiesto.

Oubaida AlQuraan
fuente
3

Solo agregue esto a su AndroidManifest.xml

<activity android:screenOrientation="landscape">

Quiero decir, hay una etiqueta de actividad, agregue esto como otro parámetro. En caso de que necesite orientación vertical, cambie de horizontal a vertical. Espero que esto ayude.

Egor
fuente
No estoy buscando eliminar la capacidad de girar la pantalla. simplemente no quiero que mi aplicación se vuelva a cargar ... como mencioné.
Jimmy D
ps ... esto no funciona de todos modos. solo obliga a la aplicación a mostrarse en una determinada orientación. rotar la pantalla todavía recarga la actividad
Jimmy D
3

En múltiples archivos agregue a cada actividad esto. Esto ayudará

android:configChanges = "orientation|keyboard|keyboardHidden|screenLayout|screenSize"
Jevgenij Kononov
fuente
screenLayout funcionó para mí, evitó la actualización al cambiar el tamaño de la aplicación para pantalla dividida en Android
Terren
2

Todas las respuestas anteriores no me funcionan. Entonces, lo solucioné mencionando el labelcon screenOrientationcomo a continuación. Ahora todo bien

<activity android:name=".activity.VideoWebViewActivity"
        android:label="@string/app_name"
        android:configChanges="orientation|screenSize"/>
Bahu
fuente
1

Guarde los detalles de la imagen en su onPause()o onStop()y úselo en onCreate(Bundle savedInstanceState)para restaurar la imagen.

EDITAR:

Más información sobre el proceso real se detalla aquí http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle ya que es diferente en Honeycomb que las versiones anteriores de Android.

techiServices
fuente
en realidad deberías hacerlo en el método onSaveInstanceState ()
Willi Mentzel el
1

Solo usa : android:configChanges="keyboardHidden|orientation"

Masoud Banimahd
fuente
1

Como mencionó Pacerier,

android:configChanges="orientation|screenSize"

Don laringe
fuente
-1

No sé si es la mejor solución, pero lo describo aquí:

En primer lugar, necesita un certificado con su clase. La aplicación de su aplicación está en su manifiesto de esto:

<application
    android:name=".App"
    ...

En segundo lugar, en la aplicación de mi clase me gustó esto:

public class App extends Application {
    public static boolean isOrientationChanged = false;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onConfigurationChanged(@NotNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ||
                newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            isOrientationChanged = true;
        }
    }

}

En tercer lugar, debe establecer un indicador en Cambio de orientación, en mi caso, siempre lo configuro cuando se llama a la actividad anterior dentro de la navegación de la aplicación, por lo que solo se llama una vez cuando se crea la actividad posterior.

isOrientationChanged = false;

Entonces, cada vez que cambio la orientación de mi pantalla en ese contexto, la configuro cada vez que cambia esta configuración, comprueba si hay un cambio en la orientación, de ser así, la valida en función del valor de esa bandera.

Básicamente, tenía que usarlo cada vez que realizaba una solicitud de modificación asincrónica, a la que llamaba cada momento que cambiaba de orientación, bloqueando constantemente la aplicación:

if (!isOrientationChanged) {
    presenter.retrieveAddress(this, idClient, TYPE_ADDRESS);
}

No sé si es la solución más elegante y hermosa, pero al menos aquí es funcional :)

michel566
fuente
-2

Agregue este código después del onCreatemétodo, en su actividad que contiene elWebView

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);    
}

@Override
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);    
}
Amir Aslam
fuente
1
¿Cómo funcionaría esto? ¿No estás diciendo algo explícitamente al tiempo de ejecución, qué se haría por defecto?
Danielson