La tua app funziona alla perfezione sugli smartphone in orientamento verticale, quindi l'hai limitata solo a questo orientamento. Ma vedi l'opportunità di fare di più sugli schermi di grandi dimensioni in orientamento orizzontale.
Come puoi fare in modo che l'app sia limitata all'orientamento verticale sugli schermi piccoli, ma che sia possibile l'orientamento orizzontale su quelli grandi?
Questa guida è una misura temporanea finché non potrai migliorare la tua app per fornire il supporto completo per tutte le configurazioni dei dispositivi.
Risultati
L'app rimane in orientamento verticale sugli schermi piccoli, indipendentemente dalla rotazione del dispositivo. Sugli schermi grandi, l'app supporta gli orientamenti orizzontale e verticale.
Gestire l'orientamento delle app
Per attivare l'orientamento orizzontale sugli schermi grandi, imposta il file manifest dell'app in modo che gestisca le modifiche dell'orientamento per impostazione predefinita. In fase di runtime, determina le dimensioni della finestra dell'app. Se la finestra dell'app è piccola, limita l'orientamento dell'app sostituendo l'impostazione di orientamento del manifest.
1. Specificare l'impostazione dell'orientamento nel manifest dell'app
Puoi evitare di dichiarare l'elemento screenOrientation
del manifest dell'app (nel qual caso l'orientamento predefinito è unspecified
) o impostare l'orientamento
dello schermo su fullUser
. Se l'utente non ha bloccato la rotazione basata sui sensori,
la tua app supporterà tutti gli orientamenti del dispositivo.
<activity
android:name=".MyActivity"
android:screenOrientation="fullUser">
La differenza tra unspecified
e fullUser
è sottile ma importante. Se
non dichiari un valore screenOrientation
, il sistema sceglie l'orientamento e il criterio utilizzato per definirlo potrebbe variare da dispositivo a dispositivo. D'altra parte, specificare fullUser
corrisponde
più da vicino al comportamento definito dall'utente per il dispositivo: se l'utente ha
bloccato la rotazione basata sui sensori, l'app segue la preferenza dell'utente; in caso contrario,
il sistema consente uno qualsiasi dei quattro orientamenti dello schermo possibili (verticale,
orizzontale, verticale inverso o orizzontale inverso). Vedi screenOrientation
.
2. Determinare le dimensioni dello schermo
Se il manifest è impostato per supportare tutti gli orientamenti consentiti dall'utente, puoi specificare l'orientamento dell'app in modo programmatico in base alle dimensioni dello schermo.
Aggiungi le librerie Jetpack WindowManager al file build.gradle
o
build.gradle.kts
del modulo:
Kotlin
implementation("androidx.window:window:version
") implementation("androidx.window:window-core:version
")
Groovy
implementation 'androidx.window:window:version
' implementation 'androidx.window:window-core:version
'
Utilizza il metodo Jetpack WindowManager
WindowMetricsCalculator#computeMaximumWindowMetrics()
per ottenere le dimensioni dello schermo del dispositivo come oggetto WindowMetrics
. Le metriche della finestra possono essere
confrontate con le classi di dimensioni della finestra per decidere quando limitare l'orientamento.
Le classi di dimensioni delle finestre forniscono i punti di interruzione tra schermi piccoli e grandi.
Utilizza i punti di interruzione WindowWidthSizeClass#COMPACT
e
WindowHeightSizeClass#COMPACT
per determinare le dimensioni dello schermo:
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; }
- Nota:
- Gli esempi vengono implementati come metodi di un'attività, pertanto l'attività viene dereferenziata come
this
nell'argomento dicomputeMaximumWindowMetrics()
. - Il metodo
computeMaximumWindowMetrics()
viene utilizzato al posto dicomputeCurrentWindowMetrics()
perché l'app può essere avviata in modalità multi-finestra, che ignora l'impostazione dell'orientamento dello schermo. Non ha senso determinare le dimensioni della finestra dell'app e ignorare l'impostazione dell'orientamento a meno che la finestra dell'app non occupi l'intero schermo del dispositivo.
Consulta WindowManager per istruzioni sulla dichiarazione delle dipendenze per rendere disponibile il metodo
computeMaximumWindowMetrics()
nella tua app.
3. Ignorare l'impostazione del manifest dell'app
Dopo aver stabilito che il dispositivo ha dimensioni dello schermo compatte, puoi chiamare
Activity#setRequestedOrientation()
per ignorare l'impostazione
screenOrientation
del manifest:
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); } } }); }
Aggiungendo la logica ai metodi onCreate()
e View.onConfigurationChanged()
, puoi ottenere le metriche della finestra massima e sostituire l'impostazione di orientamento ogni volta che l'attività viene ridimensionata o spostata tra i display, ad esempio dopo la rotazione di un dispositivo o quando un dispositivo pieghevole viene piegato o aperto.
Per ulteriori informazioni su quando si verificano le modifiche alla configurazione e quando causano la ricreazione dell'attività, consulta Gestire le modifiche alla configurazione.
Punti chiave
screenOrientation
: impostazione del manifest dell'app che ti consente di specificare in che modo l'app risponde alle modifiche dell'orientamento del dispositivo- Jetpack WindowManager: insieme di librerie che ti consentono di determinare le dimensioni e le proporzioni della finestra dell'app; compatibile con le versioni precedenti fino al livello API 14
Activity#setRequestedOrientation()
: metodo con cui puoi modificare l'orientamento dell'app in fase di runtime
Raccolte che contengono questa guida
Questa guida fa parte di queste raccolte selezionate di guide rapide che coprono obiettivi di sviluppo Android più ampi:
