La tua app funziona perfettamente sui telefoni in orientamento verticale, quindi l'hai limitata solo a questo orientamento. Tuttavia, vedi l'opportunità di fare di più sugli schermi grandi in orientamento orizzontale o sui pieghevoli aperti.
Come puoi fare entrambe le cose: limitare l'app all'orientamento verticale sullo schermo esterno di un pieghevole, ma abilitare l'orientamento orizzontale sullo schermo interno?
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.
Compatibilità con le versioni
Questa implementazione è compatibile con tutti i livelli API.
Dipendenze
Kotlin
implementation("androidx.window:window:1.5.1")
implementation("androidx.window:window-core:1.5.1")
Alla moda
implementation "androidx.window:window:1.5.1"
implementation "androidx.window:window-core:1.5.1"
Gestire l'orientamento dell'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 dell'orientamento del file manifest.
1. Specificare l'impostazione dell'orientamento nel file manifest dell'app
Puoi evitare di dichiarare l'elemento screenOrientation del file manifest dell'app (in questo caso l'orientamento è impostato su unspecified per impostazione predefinita) o impostare l'orientamento dello schermo su fullUser. Se l'utente non ha bloccato la rotazione basata sul sensore, 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 la policy utilizzata dal sistema per definire l'orientamento potrebbe variare da dispositivo a dispositivo.
D'altra parte, la specifica di fullUser corrisponde più da vicino al comportamento definito dall'utente per il dispositivo: se l'utente ha bloccato la rotazione basata sul sensore, l'app segue la preferenza dell'utente; in caso contrario, il sistema consente uno dei quattro orientamenti dello schermo possibili (verticale, orizzontale, verticale inverso o orizzontale inverso).
Inoltre, puoi utilizzare nosensor per determinare l'orientamento senza tenere conto dei dati del sensore, ma il seguente codice funzionerà allo stesso modo.
Consulta screenOrientation.
2. Determinare le dimensioni dello schermo
Con il file manifest impostato per supportare tutti gli orientamenti consentiti dall'utente, puoi specificare l'orientamento dell'app a livello di programmazione 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")
Alla moda
implementation 'androidx.window:window:version' implementation 'androidx.window:window-core:version'
Utilizza il metodo di 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 della finestra forniscono i punti di interruzione tra schermi piccoli e grandi schermi.
Utilizza i WindowSizeClass#minWidthDp e
WindowSizeClass#minHeightDp punti di interruzione per determinare le dimensioni dello schermo:
/** 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 =
BREAKPOINTS_V1.computeWindowSizeClass(width / density, height / density)
return windowSizeClass.minWidthDp == 0
}
- Nota:
- Gli esempi vengono implementati come metodi di un'attività; pertanto, l'attività viene dereferenziata come
thisnell'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 sostituire l'impostazione dell'orientamento a meno che la finestra dell'app non sia l'intero schermo del dispositivo.
Consulta WindowManager per istruzioni sulla dichiarazione delle dipendenze per rendere disponibile il
computeMaximumWindowMetrics() metodo nella tua app.
3. Sostituire l'impostazione del file manifest dell'app
Dopo aver stabilito che il dispositivo ha dimensioni dello schermo compatte, puoi chiamare
Activity#setRequestedOrientation() per sostituire l'impostazione del file manifest:
screenOrientation
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
}
})
}
Aggiungendo la logica ai metodi onCreate() e View.onConfigurationChanged(), puoi ottenere le metriche massime della finestra e sostituire l'impostazione dell'orientamento ogni volta che l'attività viene ridimensionata o spostata tra i display, ad esempio dopo una rotazione del 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.
Se utilizzi Jetpack Compose, puoi utilizzare la stessa funzione compactScreen() nel Composable principale dell'app per ottenere lo stesso risultato.
Punti chiave
screenOrientation: impostazione del file manifest dell'app che consente di specificare il modo in cui l'app risponde alle modifiche dell'orientamento del dispositivo- Jetpack WindowManager: insieme di librerie che 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 di guide rapide curate che riguardano obiettivi di sviluppo Android più ampi: