Android: permet le portrait et le paysage pour les tablettes, mais force le portrait au téléphone?

Je voudrais que les tablettes puissent être affichées en portrait et en paysage (sw600dp ou plus), mais que les téléphones soient limités au portrait. Je ne trouve aucun moyen de choisir conditionnellement une orientation. Aucune suggestion?

Voici un bon moyen d’utiliser des qualificateurs de ressources et de taille .

Placez cette ressource bool dans res / values ​​sous la forme bools.xml ou autre chose (les noms de fichiers n’ont pas d’importance ici):

    true  

Mettez celui-ci dans res / values-sw600dp et res / values-xlarge:

    false  

Voir cette réponse supplémentaire pour obtenir de l’aide sur l’ajout de ces répertoires et fichiers dans Android Studio.

Ensuite, dans la méthode onCreate de vos activités, vous pouvez le faire:

  if(getResources().getBoolean(R.bool.portrait_only)){ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } 

Les périphériques dont la largeur est supérieure à 600 dp, ou x-large sur les appareils antérieurs à Android 3.2 (tablettes, essentiellement) se comporteront normalement, en fonction de la rotation des capteurs et des utilisateurs, etc. Tout le rest (téléphones, à peu près) sera portrait seulement.

Vous pouvez essayer de cette façon d’abord obtenir la taille de l’écran de l’appareil

 if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) { Toast.makeText(this, "Large screen",Toast.LENGTH_LONG).show(); } else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) { Toast.makeText(this, "Normal sized screen" , Toast.LENGTH_LONG).show(); } else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) { Toast.makeText(this, "Small sized screen" , Toast.LENGTH_LONG).show(); } else { Toast.makeText(this, "Screen size is neither large, normal or small" , Toast.LENGTH_LONG).show(); } 

et ensuite définir l’orientation en fonction de cela

 setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

Voici comment je l’ai fait (inspiré par http://androidblogger.blogspot.com/2011/08/orientation-for-both-phones-and-tablets.html ):

Dans AndroidManifest.xml, pour chaque activité que vous souhaitez pouvoir basculer entre portrait et paysage (assurez-vous d’append screenSize – vous n’en aviez pas besoin!). Vous n’avez pas besoin de définir une orientation d’écran ici. :

 android:configChanges="keyboardHidden|orientation|screenSize" 

Méthodes à append dans chaque activité:

 public static boolean isXLargeScreen(Context context) { return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE; } 

et: (si vous ne remplacez pas cette méthode, l’application appelle onCreate () lors de la modification des orientations)

 @Override public void onConfigurationChanged (Configuration newConfig) { super.onConfigurationChanged(newConfig); if (!isXLargeScreen(getApplicationContext()) ) { return; //keep in portrait mode if a phone } //I set background images for landscape and portrait here } 

Dans onCreate () de chaque activité:

 if (!isXLargeScreen(getApplicationContext())) { //set phones to portrait; setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { //I set background images here depending on portrait or landscape orientation } 

La seule chose que je n’arrive pas à comprendre est de savoir comment faire en sorte que l’application change les fichiers de mise en page lors du passage du paysage au portrait ou vice versa. Je suppose que la réponse fait quelque chose de similaire à ce que le lien ci-dessus fait, mais je ne pouvais pas le faire fonctionner pour moi – il a supprimé toutes mes données. Mais si vous avez une application assez simple pour que vous ayez le même fichier de mise en page pour le portrait et le paysage, cela devrait fonctionner.

Supplément à la réponse acceptée

Vous pouvez effectuer les étapes suivantes dans Android Studio pour append les res/values-sw600dp et res/values-large avec leurs fichiers bools.xml .

valeurs-sw600dp

Tout d’abord, dans l’onglet Projet, sélectionnez le filtre Projet (plutôt qu’Android) dans le navigateur.

entrer la description de l'image ici

Puis cliquez avec le bouton droit sur le répertoire app/src/main/res . Choisissez Nouveau > Répertoire de ressources Android .

Sélectionnez Plus petit écran , puis appuyez sur le bouton >> .

entrer la description de l'image ici

Tapez 600 pour la plus petite largeur d’écran. Le nom du répertoire sera automatiquement généré. Dis OK.

entrer la description de l'image ici

Cliquez ensuite avec le bouton droit sur le fichier nouvellement créé values-sw600dp . Choisissez Nouveau > Fichier de ressources . Tapez bools pour le nom.

valeurs-large

L’ajout d’un répertoire values-large n’est nécessaire que si vous prenez en charge la version antérieure d’Android 3.2 (API niveau 13). Sinon, vous pouvez ignorer cette étape. Le répertoire values-large correspond aux values-sw600dp . ( values-xlarge correspond aux values-sw720dp .)

Pour créer le répertoire de values-large , suivez les mêmes étapes que ci-dessus, mais dans ce cas, choisissez la taille plutôt que la plus petite largeur d’écran. Sélectionnez Large . Le nom du répertoire sera automatiquement généré.

entrer la description de l'image ici

Cliquez avec le bouton droit sur le répertoire pour créer le fichier bools.xml .

Eh bien, c’est un peu tard, mais voici une version XML seulement, mais une solution de hack qui ne recrée pas une activité comme le fait setRequestedOrientation si elle doit changer d’orientation:

https://stackoverflow.com/a/27015879/1281930

Suite à la réponse de Ginny , je pense que la manière la plus fiable de le faire est la suivante:

Comme décrit ici , mettez un booléen dans les ressources sw600dp. Il doit avoir le préfixe sw sinon il ne fonctionnera pas correctement:

dans res / values-sw600dp / dimens.xml

   true  

dans res / values ​​/ dimens.xml

   false  

Ensuite, faites une méthode pour récupérer ce booléen:

 public class ViewUtils { public static boolean isTablet(Context context){ return context.getResources().getBoolean(R.bool.isTablet); } } 

Et une activité de base à étendre des activités pour lesquelles vous voulez ce comportement:

 public abstract class BaseActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!ViewUtils.isTablet(this)) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } } 

Ainsi, chaque activité étendrait BaseActivity:

 public class LoginActivity extends BaseActivity //.... 

Important : même si vous BaseActivity depuis BaseActivity , vous devez append la ligne android:configChanges="orientation|screenSize" à chaque Activity de votre fichier AndroidManifest.xml:

    

Ancienne question que je connais. Afin de toujours exécuter votre application en mode portrait, même lorsque l’orientation peut être ou est intervertie, etc. (par exemple sur des tablettes), j’ai conçu cette fonction pour définir l’appareil dans le bon sens, sans savoir comment le portrait et le paysage les fonctionnalités sont organisées sur l’appareil.

  private void initActivityScreenOrientPortrait() { // Avoid screen rotations (use the manifests android:screenOrientation setting) // Set this to nosensor or potrait // Set window fullscreen this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); DisplayMesortingcs mesortingcs = new DisplayMesortingcs(); this.activity.getWindowManager().getDefaultDisplay().getMesortingcs(mesortingcs); // Test if it is VISUAL in portrait mode by simply checking it's size boolean bIsVisualPortrait = ( mesortingcs.heightPixels >= mesortingcs.widthPixels ); if( !bIsVisualPortrait ) { // Swap the orientation to match the VISUAL portrait mode if( this.activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ) { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); } } else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); } } 

Fonctionne comme un charme!

AVIS: Changez this.activity activité par votre activité ou ajoutez-la à l’activité principale et supprimez this.activity activité this.activity

Si vous voulez faire le contraire, vous devez changer le code en paysage (mais je pense que c’est clair comment faire).

Malheureusement, l’utilisation de la méthode setRequestedOrientation (…) provoquera le redémarrage de l’activité. Par conséquent, même si vous appelez cette méthode dans la méthode onCreate, elle parcourra le cycle de vie de l’activité et recréera la même activité dans l’orientation demandée. Donc, à la réponse de @Brian Christensen, vous devriez considérer que le code d’activité pourrait être appelé deux fois, cela pourrait avoir des effets négatifs (non seulement visuels, mais aussi sur les requêtes réseau, les parsings, etc.).

De plus, définir l’atsortingbut configChanges dans le manifeste est à mon avis un grand compromis, ce qui pourrait nécessiter un coût de refactoring massif. Les développeurs Android ne recommandent pas de modifier cet atsortingbut .

Enfin, il est impossible, en tentant de définir le paramètre screenOrientation différemment (pour éviter le problème de redémarrage), statiquement impossible en raison du manifeste statique qui ne peut pas être modifié, il est uniquement possible d’appeler cette méthode dans l’activité déjà démarrée.

Résumé: À mon avis, la suggestion de @Brian Christensen est le meilleur compromis, mais soyez conscient du problème de redémarrage de l’activité.