Android: autoriser le portrait et le paysage pour les tablettes, mais forcer le portrait sur le téléphone?

Je voudrais que les tablettes puissent s'afficher en portrait et en paysage (sw600dp ou supérieur), mais que les téléphones soient limités au portrait seulement. Je ne trouve aucun moyen de choisir conditionnellement une orientation. Toutes les suggestions?

172
demandé sur Kenny Wyland 2012-03-09 05:34:16

8 réponses

Voici une bonne façon à l'aide de ressources et taille qualificatifs.

Mettez cette ressource bool dans res / values en tant que bools.xml ou autre (les noms de fichiers n'ont pas d'importance ici):

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <bool name="portrait_only">true</bool>
    </resources>

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

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <bool name="portrait_only">false</bool>
    </resources>

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

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

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

Périphériques qui sont plus de 600 dp dans la plus petite direction de largeur, ou X-large sur les appareils pré-Android 3.2 (tablettes, fondamentalement) se comportera comme normal, basé sur le capteur et la rotation verrouillée par l'utilisateur, etc . Tout le reste (téléphones, à peu près) sera portrait seulement.

407
répondu Brian Christensen 2017-05-23 12:03:08

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();
}

Puis définissez l'orientation en fonction de cela

setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
28
répondu Avi Kumar Manku 2014-02-21 15:03:21

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 voulez pouvoir changer entre portrait et paysage (assurez - vous d'ajouter screenSize-vous n'aviez pas besoin de cela!) Vous n'avez pas besoin de définir une orientation d'écran ici. :

android:configChanges="keyboardHidden|orientation|screenSize"

Méthodes à ajouter 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 appellera onCreate () lors du changement d'orientation)

@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 pour 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 fait le lien ci - dessus, mais je ne pouvais pas que cela fonctionne pour moi-il a supprimé toutes mes données. Mais si vous avez une application assez simple que vous avez le même fichier de mise en page pour le portrait et le paysage, cela devrait fonctionner.

8
répondu Ginny 2012-07-26 13:41:42

Supplément à la réponse acceptée

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

Valeurs-sw600dp

Tout d'abord, dans L'onglet Projet, sélectionnez le filtre projet (plutôt que Android) dans le navigateur.

entrez la description de l'image ici

Puis cliquez avec le bouton droit sur le répertoire app/src/main/res. Choisir Nouveau > Répertoire De Ressources Android .

Sélectionner plus Petite Largeur de l'Écran, puis appuyez sur la >> bouton.

entrez la description de l'image ici

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

entrez la description de l'image ici

Puis faites un clic droit sur le fichier values-sw600dp nouvellement créé. Choisir Nouveau > valeurs du fichier de ressources . Tapez bools pour le nom.

Valeurs-grand

L'ajout d'un répertoire values-large n'est nécessaire que si vous sont en charge pré Android 3.2 (API Niveau 13). Sinon, vous pouvez sauter cette étape. Le répertoire values-large correspond à values-sw600dp. (values-xlarge correspond à values-sw720dp.)

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

entrez la description de l'image ici

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

7
répondu Suragch 2017-05-23 12:10:26

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

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

4
répondu guness 2017-05-23 11:55:07

Suivant la réponse de Ginny , je pense que la façon la plus fiable de le faire est la suivante:

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

Dans res / values-sw600dp / dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="isTablet">true</bool>
</resources>

Dans res / values / dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="isTablet">false</bool>
</resources>

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 à partir des activités où vous le souhaitez 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 étendez à partir de BaseActivity, vous devez ajouter la ligne android:configChanges="orientation|screenSize" pour chaque Activity dans votre AndroidManifest.xml:

    <activity
        android:name=".login.LoginActivity"
        android:configChanges="orientation|screenSize">
    </activity>
4
répondu RominaV 2017-05-23 11:55:07

Vieille question que je connais. Pour exécuter votre application en mode portrait, même lorsque l'orientation peut être ou est échangé etc (par exemple sur les tablettes), j'ai conçu cette fonction est utilisée pour régler l'appareil dans le bon sens sans le besoin de savoir comment le portrait et les caractéristiques du paysage 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);

        DisplayMetrics metrics = new DisplayMetrics();
        this.activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

         // Test if it is VISUAL in portrait mode by simply checking it's size
        boolean bIsVisualPortrait = ( metrics.heightPixels >= metrics.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: Modifiez this.activity par votre activité ou ajoutez-le à l'activité principale et supprimez this.activity ;-)

Si vous voulez faire le en face, vous devez changer le code en paysage (mais je pense qu'il est clair comment cela).

0
répondu Codebeat 2014-03-13 15:54:21

Malheureusement, en utilisant la méthode setRequestedOrientation(...) provoquera le redémarrage de l'activité, donc même si vous appelez cela dans la méthode onCreate, il passera par 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é peut être appelé deux fois, cela pourrait avoir de mauvais effets (non seulement visuels, mais aussi sur les requêtes réseau, les analyses, etc.).

En outre, pour définir l'attribut configChanges dans le manifeste est à mon avis Un gros compromis, ce qui pourrait prendre un coût de refactoring massif. les développeurs Android ne recommandent pas de modifier cet attribut .

Enfin, essayer de définir l'orientation de l'écran différemment (pour éviter le problème de redémarrage)est impossible, statiquement impossible en raison du Manifeste statique qui ne peut pas être modifié, par programmation, il est seulement 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 l'activité de redémarrage.

0
répondu mathew11 2017-11-03 16:01:15