Não recarregue o aplicativo quando a orientação mudar

152

Eu simplesmente não preciso de nada para mudar quando a tela é girada. Meu aplicativo exibe uma imagem aleatória quando é carregado pela primeira vez e a rotação do dispositivo não deve selecionar outra imagem aleatória. Como posso (simplesmente) fazer esse comportamento parar?

Jimmy D
fonte
1
Também é possível bloquear (e possivelmente desbloquear) a orientação da tela a partir do código. Basta ligar Screen.lockOrientation(this)de github.com/delight-im/Android-BaseLib/blob/master/Source/src/im/… para isso. Permite desbloquear o que o manifesto não permite.
caw
@Escobar Ceaser Qual é a solução adequada para esta pergunta. Mesmo que eu tenha o mesmo requisito.
Prabs
Eu gostaria de fazer isso programaticamente em código.
pollaris 27/09/17

Respostas:

249

Geralmente, existem três maneiras de fazer isso:

  1. Como algumas das respostas sugeridas, você pode distinguir os casos de sua atividade sendo criada pela primeira vez e restaurada savedInstanceState. Isso é feito sobrescrevendo onSaveInstanceStatee verificando o parâmetro de onCreate.

  2. Você pode bloquear a atividade em uma orientação adicionando android:screenOrientation="portrait"(ou "landscape") ao <activity>seu manifesto.

  3. Você pode dizer ao sistema que pretende lidar com as alterações na tela especificando android:configChanges="orientation|screenSize"na <activity>tag. Dessa forma, a atividade não será recriada, mas receberá um retorno de chamada (que você pode ignorar, pois não é útil para você).

Pessoalmente, eu iria com (3). Obviamente, se bloquear o aplicativo em uma das orientações é bom para você, você também pode ir com (2).

Xion
fonte
13
Então, para o número 3, você está dizendo que tudo o que preciso fazer é adicionar essa linha ao meu manifesto? Porque isso não funciona.
Jimmy D
16
@EscobarCeaser, For Android 3.2 e acima, você precisaandroid:configChanges="orientation|screenSize"
Pacerier
9
android:configChanges="orientation|screenSize"funciona para mim. Obrigado @Pacerier
Don Larynx
1
atualize seu caso de resposta nº 3 com o android:configChanges="orientation|screenSize"valor da API> = 13, porque muitas pessoas vêem sua resposta como principal!
Radistao 11/07/2015
215

A resposta de Xion foi próxima, mas o item 3 ( android:configChanes="orientation") não funcionará, a menos que o aplicativo tenha um nível de API igual ou inferior a 12.

No nível 13 ou superior da API, o tamanho da tela muda quando a orientação é alterada, portanto, isso ainda causa a destruição da atividade e o início da mudança.

Basta adicionar o atributo "screenSize", como fiz abaixo:

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

Agora, quando você altera a orientação (e o tamanho da tela muda), a atividade mantém seu estado e onConfigurationChanged()é chamada. Isso manterá o que estiver na tela (por exemplo: página da web em uma visualização na web) quando a orientação mudar.

Aprendi isso neste site: http://developer.android.com/guide/topics/manifest/activity-element.html

Além disso, essa é aparentemente uma prática ruim, então leia o link abaixo sobre o tratamento de alterações no tempo de execução:

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

corbin
fonte
2
Graças ... seu trabalho depois acrescentou: "screensize" com "orientação"
Pratik Butani
Funciona no Samsung Galaxy Nexus android 4.2.1! android:configChanges="orientation|screenSize"
Vincent Ducastel 15/03/2014
Surpreendente. Estou trabalhando com o código há muitas horas para resolver um problema que tive com o recarregamento de atividades e um vídeo a partir do início. E aqui estava a solução! ++++ 1
Mathias Asberg
6
Má prática? Pfft, vida real as pessoas têm prazos e se ele funciona, ele funciona;)
Kacy
Se essa é uma prática ruim, por que ficou com tantos votos positivos ??
Sharp Edge
26

Você só precisa acessar os AndroidManifest.xmlrótulos de dentro e de dentro de suas atividades; digitar esta linha de código como alguém lá em cima disse:

android:configChanges="orientation|screenSize"

Então, você terá algo parecido com isto:

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

Espero que funcione!

Josue Rocha
fonte
não está carregando meu layout-land layout. :( não funcionou para mim
piyush poriya 21/10
16
<activity android:name="com.example.abc" 
 android:configChanges="orientation|screenSize"></activity>

Basta adicionar android:configChanges="orientation|screenSize"na guia de atividade do arquivo de manifesto.

Portanto, a atividade não será reiniciada quando a orientação mudar.

Aiyaz Parmar
fonte
Está funcionando. Mas quando estou usando um layout separado para cada orientação layout.xml e layout-land.xml. aplicando o layout da paisagem para ambas as orientações. Se eu usar apenas "orientação", está dando o que espero, mas recarregando. Você poderia ajudar nisso?
precisa
1
@KarthikeyanVe Esse é o problema quando você está tentando trapacear. Você vai ter de reiniciar sua atividade para layout de mudança. Vá em frente e use a solução real, que está usando onSaveInstanceState()e onCreate().
Marc Plano-Lesay
@ MarcPlano-Lesay e como devo fazer isso?
Ahsan
@Weaboo, a solução real está vinculada na pergunta: developer.android.com/guide/topics/resources/…
Marc Plano-Lesay
@ MarcPlano-Lesay Eu tenho um layout separado para os modos retrato e paisagem; se eu abrir o aplicativo no modo paisagem ou retrato, ele funcionará bem, mas sempre que tento alterar a orientação no tempo de execução, ele fecha o aplicativo; no entanto, quando faço login no aplicativo e, em seguida, navegue para MainActivity e tente alterar a orientação, recarrega essa atividade e funciona bem. Agora a pergunta é por quê? Existe um erro lógico no meu código? Idk, mas eu tentei depurar o aplicativo várias vezes e não consigo encontrar nada. Além disso, não quero reiniciar minha atividade, por que não podemos simplesmente adaptar o layout respectivo sempre que a configuração é alterada?
Ahsan
10

É minha experiência que é realmente melhor lidar com as mudanças de orientação corretamente, em vez de tentar calçar um comportamento não padrão.

Você deve salvar a imagem exibida no momento onSaveInstanceState()e restaurá-la corretamente quando o aplicativo for executado onCreate()novamente.

dmon
fonte
# 3 é uma solução perfeitamente válida. É a ferramenta exata feita para resolver esse problema exato. Por que você diz que é calçadeira?
Pacerier #
1
@ Pacerier Basta ler os documentos. "Nota: O uso android:configChangesdeve ser evitado e usado apenas como último recurso. Leia Manipulando alterações no tempo de execução para obter mais informações sobre como lidar adequadamente com uma reinicialização devido a uma alteração na configuração."
Marc Plano-Lesay
Você poderia postar um exemplo para salvar e restaurar.
pollaris
6

Esta solução é de longe a melhor que funciona. No seu arquivo de manifesto, adicione

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

E na sua classe de atividade, adicione o seguinte 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

    }
}
A Raj
fonte
4

adicione android:configChanges="keyboardHidden|orientation|screenSize"para todas as tags de atividades do aplicativo no manifesto.

Oubaida AlQuraan
fonte
3

Basta adicionar isso ao seu AndroidManifest.xml

<activity android:screenOrientation="landscape">

Quero dizer, há uma tag de atividade, adicione isso como outro parâmetro. Caso precise de orientação para retrato, mude paisagem para retrato. Espero que isto ajude.

Egor
fonte
não estou tentando tirar a capacidade de girar a tela. Eu só não quero o meu aplicativo para recarregar ... como eu mencionei.
Jimmy D
ps ... isso não funciona de qualquer maneira. apenas força o aplicativo a ser exibido em uma determinada orientação. girar a tela ainda recarrega a atividade
Jimmy D
3

No arquivo mais manifesto, adicione a cada atividade isso. Isso vai ajudar

android:configChanges = "orientation|keyboard|keyboardHidden|screenLayout|screenSize"
Jevgenij Kononov
fonte
screenLayout trabalhou para mim, refrescar impedido quando redimensionar app para tela dividida no android
Terren
2

Todas as respostas acima não estão funcionando para mim. Então, eu corrigi mencionando o labelcom screenOrientationcomo abaixo. Agora está tudo bem

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

Salve os detalhes da imagem no seu onPause()ou onStop()use-o no onCreate(Bundle savedInstanceState)para restaurar a imagem.

EDITAR:

Mais informações sobre o processo real estão detalhadas aqui http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle , pois é diferente no Honeycomb do que nas versões anteriores do Android.

techiServices
fonte
na verdade, você deve fazê-lo no método onSaveInstanceState ()
Willi Mentzel
1

Apenas use : android:configChanges="keyboardHidden|orientation"

Masoud Banimahd
fonte
1

Como Pacerier mencionou,

android:configChanges="orientation|screenSize"

Don Larynx
fonte
-1

Não sei se é a melhor solução, mas descrevo-a aqui:

Primeiro de tudo, você precisa de um certificado com sua classe O aplicativo do seu aplicativo está no manifesto disso:

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

Segundo, na minha classe App, eu fiz assim:

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;
        }
    }

}

Terceiro, você precisa definir um sinalizador para Mudança de orientação, no meu caso, eu sempre o defino quando a atividade anterior na navegação do aplicativo é chamada, portanto, é só chamar uma vez quando a atividade posterior é criada.

isOrientationChanged = false;

Portanto, toda vez que altero a orientação da minha tela nesse contexto, defino-a sempre que altera essa configuração, verifica se há uma alteração na orientação; nesse caso, valida-a com base no valor desse sinalizador.

Basicamente, eu precisava usá-lo sempre que fazia uma solicitação de atualização assíncrona, que ele chamava a cada momento que mudava de orientação, travando constantemente o aplicativo:

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

Não sei se é a solução mais elegante e bonita, mas pelo menos aqui é funcional :)

michel566
fonte
-2

Adicione esse código após o onCreatemétodo, em sua atividade que contém oWebView

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

@Override
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);    
}
Amir Aslam
fonte
1
Como isso funcionaria? Você não está apenas dizendo algo explicitamente ao tempo de execução, o que de outra forma seria feito por padrão?
9159 Danielson