Como o app funciona muito bem em smartphones na orientação retrato, você o restringiu apenas a esse modo. Mas você percebe uma oportunidade de melhorar o suporte do app em telas grandes na orientação paisagem.
Como você pode aproveitar o melhor de dois mundos, restringindo o app à orientação retrato em telas pequenas, mas ativando o modo paisagem em telas grandes?
Este guia é uma medida temporária até que você melhore o app para oferecer suporte total a todas as configurações de dispositivos.
Gerenciar a orientação do app
Para ativar a orientação paisagem em telas grandes, defina o manifesto do app para processar mudanças de orientação por padrão. Durante a execução, determine o tamanho da janela do app. Se a janela do app for pequena, restrinja a orientação do app substituindo a configuração de orientação do manifesto.
1. Especificar a configuração de orientação no manifesto do app
Você pode evitar declarar o elemento screenOrientation
do manifesto
do app, o que define a orientação padrão como unspecified
, ou pode definir a orientação
da tela como fullUser
. Se o usuário não tiver bloqueado a rotação com base no sensor,
o app vai oferecer suporte a todas as orientações do dispositivo.
<activity
android:name=".MyActivity"
android:screenOrientation="fullUser">
A diferença entre unspecified
e fullUser
é sutil, mas importante. Se
você não declarar um valor screenOrientation
, o sistema vai escolher a
orientação, e a política usada para defini-la poderá
variar de acordo com o dispositivo. Por outro lado, especificar fullUser
corresponde
mais de perto ao comportamento definido pelo usuário para o dispositivo: se o usuário bloqueou
a rotação com base em sensor, o app segue a preferência do usuário. Caso contrário,
o sistema permite qualquer uma das quatro orientações de tela possíveis (retrato,
paisagem, retrato invertido ou paisagem invertida). Consulte screenOrientation
.
2. Determinar o tamanho da tela
Com o manifesto definido para oferecer suporte a todas as orientações permitidas pelo usuário, você pode especificar a orientação do app de forma programática com base no tamanho da tela.
Adicione as bibliotecas Jetpack WindowManager ao arquivo build.gradle
ou
build.gradle.kts
do módulo:
Kotlin
implementation("androidx.window:window:version
") implementation("androidx.window:window-core:version
")
Groovy
implementation 'androidx.window:window:version
' implementation 'androidx.window:window-core:version
'
Use o método WindowMetricsCalculator#computeMaximumWindowMetrics()
da Jetpack WindowManager para conferir o
tamanho da tela do dispositivo como um objeto WindowMetrics
. As métricas da janela podem ser
comparadas a classes de tamanho de janela para decidir quando restringir a orientação.
As classes de tamanho de janelas oferecem os pontos de interrupção entre telas pequenas e grandes.
Use os pontos de interrupção WindowWidthSizeClass#COMPACT
e
WindowHeightSizeClass#COMPACT
para determinar o tamanho da tela:
Kotlin
/** Determines whether the device has a compact screen. **/ fun compactScreen() : Boolean { val metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this) val width = metrics.bounds.width() val height = metrics.bounds.height() val density = resources.displayMetrics.density val windowSizeClass = WindowSizeClass.compute(width/density, height/density) return windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT || windowSizeClass.windowHeightSizeClass == WindowHeightSizeClass.COMPACT }
Java
/** Determines whether the device has a compact screen. **/ private boolean compactScreen() { WindowMetrics metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this); int width = metrics.getBounds().width(); int height = metrics.getBounds().height(); float density = getResources().getDisplayMetrics().density; WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density); return windowSizeClass.getWindowWidthSizeClass() == WindowWidthSizeClass.COMPACT || windowSizeClass.getWindowHeightSizeClass() == WindowHeightSizeClass.COMPACT; }
- Observação:
- Os exemplos são implementados como métodos de uma atividade. A atividade é desreferenciada como
this
no argumento decomputeMaximumWindowMetrics()
. - O método
computeMaximumWindowMetrics()
é usado em vez decomputeCurrentWindowMetrics()
porque o app pode ser iniciado no modo de várias janelas, que ignora a configuração de orientação da tela. Não há sentido em determinar o tamanho da janela do app e substituir a configuração de orientação, a menos que a janela do app seja a tela inteira do dispositivo.
Consulte WindowManager para instruções sobre como declarar dependências e disponibilizar o
método computeMaximumWindowMetrics()
no app.
3. Substituir a configuração do manifesto do app
Se você determinar que o dispositivo tem um tamanho de tela compacto, chame
Activity#setRequestedOrientation()
para substituir a configuração
screenOrientation
do manifesto:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) requestedOrientation = if (compactScreen()) ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else ActivityInfo.SCREEN_ORIENTATION_FULL_USER ... // Replace with a known container that you can safely add a // view to where the view won't affect the layout and the view // won't be replaced. val container: ViewGroup = binding.container // Add a utility view to the container to hook into // View.onConfigurationChanged. This is required for all // activities, even those that don't handle configuration // changes. You can't use Activity.onConfigurationChanged, // since there are situations where that won't be called when // the configuration changes. View.onConfigurationChanged is // called in those scenarios. container.addView(object : View(this) { override fun onConfigurationChanged(newConfig: Configuration?) { super.onConfigurationChanged(newConfig) requestedOrientation = if (compactScreen()) ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else ActivityInfo.SCREEN_ORIENTATION_FULL_USER } }) }
Java
@Override protected void onCreate(Bundle savedInstance) { super.onCreate(savedInstanceState); if (compactScreen()) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER); } ... // Replace with a known container that you can safely add a // view to where the view won't affect the layout and the view // won't be replaced. ViewGroup container = binding.container; // Add a utility view to the container to hook into // View.onConfigurationChanged. This is required for all // activities, even those that don't handle configuration // changes. You can't use Activity.onConfigurationChanged, // since there are situations where that won't be called when // the configuration changes. View.onConfigurationChanged is // called in those scenarios. container.addView(new View(this) { @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (compactScreen()) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER); } } }); }
Ao adicionar a lógica aos métodos onCreate()
e View.onConfigurationChanged()
,
você poderá acessar as métricas máximas da janela e substituir a
configuração de orientação sempre que a atividade for redimensionada ou movida entre as telas,
por exemplo, após uma rotação do dispositivo ou quando um dispositivo dobrável for dobrado ou desdobrado.
Para mais informações sobre quando as mudanças de configuração ocorrem e quando elas causam
a recriação de atividades, consulte Gerenciar mudanças de configuração.
Pontos principais
screenOrientation
: configuração do manifesto do app que permite especificar como o app responde às mudanças de orientação do dispositivo.- Jetpack WindowManager: conjunto de bibliotecas que permitem determinar o tamanho e a proporção da janela do app. Ele é compatível com o nível 14 da API e versões mais recentes.
Activity#setRequestedOrientation()
: método com que é possível mudar a orientação do app no momento da execução.
Resultados
Agora, o app vai permanecer na orientação retrato em telas pequenas, independente da rotação do dispositivo. Em telas grandes, o app precisa oferecer suporte às orientações de paisagem e retrato.
Coleções que contêm este guia
Este guia faz parte destas coleções selecionadas de guias rápidos que abrangem objetivos mais amplos de desenvolvimento para Android:
![](https://developer.android.com/static/images/quick-guides/collection-illustration.png?hl=pt-br)