Orientation de l'application limitée sur les téléphones, mais pas sur les grands écrans

Icône de note à deux étoiles

Votre application fonctionne parfaitement sur les téléphones en mode portrait. Vous avez donc limité l'application à ce mode. Toutefois, vous savez que le mode paysage permettrait d'en faire plus sur les grands écrans.

Comment limiter l'orientation portrait de l'application aux petits écrans, tout en permettant le mode paysage sur les grands écrans ?

Bonnes pratiques

Les meilleures applications respectent les préférences utilisateur telles que l'orientation de l'appareil.

Les consignes relatives à la qualité des applis adaptatives recommandent que les applications soient compatibles avec toutes les configurations d'appareil, y compris les orientations portrait et paysage, le mode multifenêtre ou l'état plié et déplié des appareils pliables. Les applications doivent optimiser les mises en page et les interfaces utilisateur en fonction des différentes configurations. Elles doivent aussi enregistrer et restaurer l'état lors des changements de configuration.

La recette qui suit est une mesure temporaire : elle offre un zeste de compatibilité avec les grands écrans. Utilisez cette recette jusqu'à ce que votre application soit entièrement compatible avec toutes les configurations d'appareils.

Ingrédients

  • screenOrientation: paramètre de fichier manifeste d'application qui vous permet de spécifier la manière dont votre application réagit aux changements d'orientation de l'appareil.
  • Activity#setRequestedOrientation(): méthode vous permettant de modifier l'orientation de l'application au moment de l'exécution.
  • LocalConfiguration : fournisseur local composable qui expose la actuelle de l'appareil Configuration, ce qui vous permet de lire les dimensions de l'écran en dp.
  • LaunchedEffect: API d'effet secondaire Compose qui exécute un bloc de code lorsqu'une clé change (dans ce cas, lorsque la configuration change).

Étapes

Autorisez l'application à gérer les changements d'orientation par défaut dans son fichier manifeste. Ensuite, au moment de l'exécution, utilisez Jetpack Compose pour limiter dynamiquement l'orientation au mode portrait sur les écrans compacts (téléphones) tout en autorisant toutes les orientations sur les grands écrans.

1. Spécifier le paramètre d'orientation dans le fichier manifeste de l'application

Vous pouvez éviter de déclarer l'élément screenOrientation du fichier manifeste d'application (dans ce cas, l'orientation par défaut est unspecified) ou définir l'orientation de l'écran sur fullUser. Si l'utilisateur n'a pas verrouillé la rotation basée sur le capteur, votre application accepte toutes les orientations d'appareil.

<activity
    android:name=".MyActivity"
    android:screenOrientation="fullUser">

La différence entre unspecified et fullUser est subtile, mais importante. Si vous ne déclarez pas de valeur screenOrientation, le système choisit l'orientation, et la règle qu'il utilise pour la définir peut varier d'un appareil à l'autre. En revanche, spécifier fullUser correspond mieux au comportement que l'utilisateur a défini pour l'appareil : si l'utilisateur a verrouillé la rotation basée sur le capteur, l'application suit ses préférences. Dans le cas contraire, le système autorise l'une des quatre orientations d'écran possibles (portrait, paysage, portrait inversé ou paysage inversé). Consultez android:screenOrientation.

2. Limiter dynamiquement l'orientation dans Compose

Dans Jetpack Compose, vous pouvez lire les dimensions actuelles de l'écran en dp de manière réactive à partir de LocalConfiguration.current et utiliser un LaunchedEffect pour mettre à jour l'orientation de l'activité chaque fois que la configuration change.

Si la largeur ou la hauteur de l'écran est inférieure à 600dp (ce qui correspond au point d'arrêt compact pour les téléphones), limitez l'orientation au mode portrait. Sinon, autorisez le système à faire pivoter l'application en fonction des préférences de l'utilisateur (unspecified ou fullUser).

Voici l'implémentation complète et compilable :

val configuration = LocalConfiguration.current
val context = LocalActivity.current

LaunchedEffect(configuration) {
    val activity = context ?: return@LaunchedEffect
    // Determine if screen is compact (phone-sized) in either width or height
    val isCompact = configuration.screenWidthDp < 600 || configuration.screenHeightDp < 600
    activity.requestedOrientation = if (isCompact) {
        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    } else {
        ActivityInfo.SCREEN_ORIENTATION_FULL_USER
    }
}

En ajoutant la logique dans un bloc LaunchedEffect(configuration), vous pouvez remplacer de manière réactive le paramètre d'orientation chaque fois que la configuration de l'application change, par exemple lorsque l'activité est redimensionnée, déplacée entre les écrans ou lorsqu'un appareil pliable est plié ou déplié.

Pour savoir quand des modifications de configuration se produisent et à quel moment elles provoquent la recréation d'une activité, consultez la section Gérer les modifications de configuration.

Résultats

Votre application devrait désormais rester en mode portrait sur les petits écrans, quelle que soit la rotation de l'appareil. Sur les grands écrans, elle devrait être compatible avec les orientations paysage et portrait.

Ressources supplémentaires

Pour découvrir comment mettre à niveau de votre application afin qu'elle soit toujours compatible avec toutes les configurations d'appareil, consultez les ressources suivantes :