Comment verrouiller l'orientation pendant l'exécution

107

Existe-t-il un moyen de verrouiller l'orientation pendant l'exécution? Par exemple, je voudrais permettre à l'utilisateur de verrouiller l'écran en paysage si l'utilisateur est actuellement en mode paysage et de basculer l'option de menu.

Jared
la source

Réponses:

133
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Appelé sur une activité, la verrouille en mode paysage. Recherchez les autres indicateurs dans la classe ActivityInfo. Vous pouvez le verrouiller en mode portrait ou le faire fonctionner par capteur / curseur.

Plus d'informations ici: http://www.devx.com/wireless/Article/40792

haseman
la source
13
OK merci. Cela fonctionne très bien. Cela obtiendra l'orientation actuelle. getResources (). getConfiguration (). orientation
Jared
7
Prudent! Vous devez faire la différence entre ce que renvoie getConfiguration () et ce que veut setRequestedOrientation - voir ma réponse ci-dessous pour plus de détails
Andy Weinstein
il y a un problème avec cette approche. Assurez-vous de lire le commentaire de cette réponse
Bugs Happen
mais il définit la même orientation pour toute l'activité, y a-t-il un autre moyen de changer l'orientation
silverFoxA
106

Faites attention à la différence entre ce que renvoie getConfiguration et ce que veut setRequestedOrientation - ils sont tous les deux int, mais ils proviennent de définitions de constantes différentes.

Voici comment verrouiller l'orientation actuelle, tout en permettant des retournements à 180 degrés

int currentOrientation = getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
else {
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
Andy Weinstein
la source
13
Vous préférerez peut-être utiliser SCREEN_ORIENTATION_USER_LANDSCAPE car cela n'autorise pas les retournements à 180 degrés si l'utilisateur a désactivé la rotation de l'écran dans les paramètres. De même lors du retour en rotation libre, SCREEN_ORIENTATION_USER est meilleur que SCREEN_ORIENTATION_SENSOR car ce dernier permet une rotation libre même si les paramètres le disent non.
Steve Waring
Brillant! Il faut ajouter que lorsque vous passez à l'orientation inversée, la reconfiguration ne se produit pas. Au moins sur les appareils sur lesquels je l'ai testé. Il est vraiment important de savoir si vous voulez reconfiguration d'arrêt lors de certains spectacles de dialogue etc
sberezin
47

Cela fonctionne sur les appareils avec portrait inversé et paysage inversé.

Verrouiller l'orientation:

    int orientation = getActivity().getRequestedOrientation();
    int rotation = ((WindowManager) getActivity().getSystemService(
            Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
    switch (rotation) {
    case Surface.ROTATION_0:
        orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        break;
    case Surface.ROTATION_90:
        orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        break;
    case Surface.ROTATION_180:
        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
        break;
    default:
        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
        break;
    }

    getActivity().setRequestedOrientation(orientation);

Déverrouiller l'orientation:

   getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
pstoppani
la source
5
Obtenez la "Returns the rotation of the screen from its "natural" orientation." source de rotation . Ainsi, sur un téléphone disant que ROTATION_0 est portrait est probablement correct, mais sur une tablette, son orientation «naturelle» est probablement paysage et ROTATION_0 devrait renvoyer paysage au lieu de portrait.
jp36
@ jp36, j'ai testé sur un Nexus 7 qui a une orientation naturelle qui est la même qu'un téléphone. Merci d'avoir testé sur une plus grande tablette (que je n'ai pas).
pstoppani
1
Comme jp36 l'a dit, cela ne fonctionne pas sur les tablettes avec une orientation paysage naturelle!
DominicM
Comment tester le portrait inversé dans l'appareil?
AndyBoy
27

J'avais l'air d'avoir un cas similaire. Je voulais prendre en charge n'importe quelle orientation, mais je devais rester dans l'orientation actuelle après un certain point du flux de travail. Ma solution était:

A l'entrée du workflow protégé:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

A la sortie du workflow protégé:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
Stefan Bachert
la source
2
Cela ne répond pas à l'OQ, du moins sur Android> = 16. setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) peut mettre l'appareil en paysage même s'il était en portrait, alors que la question se réfère à l'orientation de verrouillage qui a été donnée.
greg7gkb
3
pour moi, le régler sur nosensor me ramène au mode portrait si j'étais en mode paysage J'ai utilisé SCREEN_ORIENTATION_LOCKED à la place et cela a fonctionné pour moi
Jimmar
1
@JiMMaR SCREEN_ORIENTATION_LOCKED est le meilleur moyen pour Android> = 18. Mais si vous ciblez quelque chose de plus bas, cela ne fonctionne pas. Je suggère d'utiliser la réponse de jp36 ci-dessous.
Patrick Boos
23

Alternative à la réponse @pstoppani avec prise en charge des tablettes (comme pour la réponse @pstoppani, cela ne fonctionnera que sur les appareils> 2.2)
-Testé sur Samsung Galaxy SIIIetSamsung Galaxy Tab 10.1

public static void lockOrientation(Activity activity) {
    Display display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    int rotation = display.getRotation();
    int tempOrientation = activity.getResources().getConfiguration().orientation;
    int orientation = 0;
    switch(tempOrientation)
    {
    case Configuration.ORIENTATION_LANDSCAPE:
        if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90)
            orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        else
            orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
        break;
    case Configuration.ORIENTATION_PORTRAIT:
        if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270)
            orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        else
            orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
    }
    activity.setRequestedOrientation(orientation);
}
jp36
la source
Merci, ça fonctionne bien , mais je ne comprenais pas pourquoi il est que vérifier avec ||dans rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90et avec rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270. Donc, j'ai 2 doute :::: d'abord, pourquoi ROTATION_0au lieu de ROTATION_180dans le deuxième cas et un autre pourquoi vérifier 0 degré avec 90 pas 180 ??
AndyBoy
@AndyBoy cela a à voir avec l'orientation par défaut des appareils. En règle générale, les téléphones ont une orientation par défaut de portrait, ce qui signifie que la rotation renvoie zéro pour le portrait, mais certaines tablettes ont une valeur par défaut de paysage, ce qui signifie que la rotation renvoie zéro pour le paysage. Ainsi, les différentes ||vérifications gèrent les deux orientations par défaut possibles basées sur le rapport de l'appareil paysage vs portrait.
jp36
5

Voici mon code, vous pouvez verrouiller avec l'une de ces méthodes votre écran et une fois la tâche terminée, le déverrouiller avec unlockOrientation:

/** Static methods related to device orientation. */
public class OrientationUtils {
    private OrientationUtils() {}

    /** Locks the device window in landscape mode. */
    public static void lockOrientationLandscape(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

    /** Locks the device window in portrait mode. */
    public static void lockOrientationPortrait(Activity activity) {
    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    /** Locks the device window in actual screen mode. */
    public static void lockOrientation(Activity activity) {
        final int orientation = activity.getResources().getConfiguration().orientation;
        final int rotation = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();

        // Copied from Android docs, since we don't have these values in Froyo 2.2
        int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
        int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;

        // Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO
        if (!BuildVersionUtils.hasGingerbread()) {
            SCREEN_ORIENTATION_REVERSE_LANDSCAPE = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            SCREEN_ORIENTATION_REVERSE_PORTRAIT = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        }

        if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90){
            if (orientation == Configuration.ORIENTATION_PORTRAIT){
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
            else if (orientation == Configuration.ORIENTATION_LANDSCAPE){
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            }
        }
        else if (rotation == Surface.ROTATION_180 || rotation == Surface.ROTATION_270) 
        {
            if (orientation == Configuration.ORIENTATION_PORTRAIT){
                activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_PORTRAIT);
            }
            else if (orientation == Configuration.ORIENTATION_LANDSCAPE){
                activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
            }
        }
    }

    /** Unlocks the device window in user defined screen mode. */
    public static void unlockOrientation(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
    }

}
madx
la source
0

Voici la conversion Xamarin de la réponse de @pstoppani ci-dessus.

REMARQUE: il s'agit d'un fragment, remplacez l' activité. avec ça. s'il est utilisé dans une activité.

public void LockRotation()
{
    ScreenOrientation orientation;

    var surfaceOrientation = Activity.WindowManager.DefaultDisplay.Rotation;

    switch (surfaceOrientation) {
        case SurfaceOrientation.Rotation0:
            orientation = ScreenOrientation.Portrait;
            break;
        case SurfaceOrientation.Rotation90:
            orientation = ScreenOrientation.Landscape;
            break;
        case SurfaceOrientation.Rotation180:
            orientation = ScreenOrientation.ReversePortrait;
            break;
        default:
            orientation = ScreenOrientation.ReverseLandscape;
            break;
    }

    Activity.RequestedOrientation = orientation;
}

public void UnlockRotation()
{
    Activity.RequestedOrientation = ScreenOrientation.Unspecified;
}

Ceci n'a pas été testé comme cela était allé avec une approche différente avant de l'utiliser, mais peut être utile.

WickedW
la source
C'est la même réponse que celle de pstoppani, et elle échouera sur une tablette.
Tim Autin