Як заблокувати орієнтацію під час виконання


107

Чи є спосіб блокувати орієнтацію під час виконання? Наприклад, я хотів би дозволити користувачеві заблокувати екран для пейзажу, якщо користувач зараз перебуває в альбомному режимі та перемкнути параметр меню.

Відповіді:


133
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Зателефонований на діяльність, заблокує її до пейзажу. Шукайте інші прапори класу ActivityInfo. Ви можете зафіксувати його назад до портрета або зробити його сенсором / повзунком.

Більше інформації тут: http://www.devx.com/wireless/Article/40792


13
Добре, дякую. Це чудово працює. Це отримає поточну орієнтацію. getResources (). Орієнтація getConfiguration ().
Джаред

7
Обережно! Вам потрібно розмежовувати те, що повертає getConfiguration (), і те, що бажає setRequestedOrientation - див. Мою відповідь нижче для деталей
Енді Вайнштейн

з цим підходом виникає проблема. Обов’язково перегляньте коментар до цієї відповіді
Помилки трапляються

але вона встановлює однакову орієнтацію для всіх видів діяльності, чи є інший спосіб, де ми можемо змінити орієнтацію
silverFoxA

106

Будьте уважні до різниці між тим, що getConfiguration повертається, і тим, що setRequestedOrientation хоче - вони обидва int, але вони виходять з різних постійних визначень.

Ось як заблокувати поточну орієнтацію, дозволяючи відвернути 180 градусів

int currentOrientation = getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
else {
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}

13
Ви можете скористатися SCREEN_ORIENTATION_USER_LANDSCAPE, оскільки це не дозволяє перевертати на 180 градусів, якщо користувач відключив обертання екрана в налаштуваннях. Аналогічно при переході назад до вільного обертання SCREEN_ORIENTATION_USER краще, ніж SCREEN_ORIENTATION_SENSOR, оскільки останній дозволяє вільне обертання, навіть якщо налаштування скажуть, що це не робити.
Стів Варінг

Блискуче! Необхідно додати, що при переході на зворотну орієнтацію перенастроювання не відбувається. Принаймні, на пристроях, на яких я тестував. Дійсно важливо знати, чи хочете ви зупинити конфігурацію під час деяких діалогових шоу тощо
sberezin

47

Це працює на пристроях із зворотним портретом та зворотним пейзажем.

Орієнтація блокування:

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

Розблокувати орієнтацію:

   getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

5
Отримайте "Returns the rotation of the screen from its "natural" orientation." джерело обертання . Отже, по телефону, що говорить ROTATION_0 - портрет, швидше за все, правильно, але на планшеті його "природна" орієнтація - це, ймовірно, пейзаж, і ROTATION_0 повинен повертати пейзаж замість портрета.
jp36

@ jp36, я тестував Nexus 7, який має природну орієнтацію, таку ж, що і телефон. Дякуємо за тестування на більшому планшеті (якого у мене немає).
pstoppani

1
Як сказав jp36, він не працює на планшетах із природною ландшафтною орієнтацією!
DominicM

Як ми тестуємо зворотний портрет на пристрої ??
AndyBoy

27

У мене, здавалося, був подібний випадок. Я хотів підтримати будь-яку орієнтацію, але мені потрібно було залишатися в поточній орієнтації після певного моменту робочого процесу. Моє рішення було:

При введенні захищеного робочого процесу:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

На виході із захищеного робочого процесу:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

2
Це не стосується ОК, принаймні, на Android> = 16. setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) може встановити пристрій на ландшафт, навіть якщо він був у портреті, тоді як питання стосується заданої орієнтації блокування.
greg7gkb

3
для мене, якщо встановити його на носорі, повертає мене до портретного режиму, якщо я був на пейзажі, я натомість використав SCREEN_ORIENTATION_LOCKED, і це працювало для мене
Джиммар

1
@JiMMaR SCREEN_ORIENTATION_LOCKED - найкращий спосіб для Android> = 18. Але якщо ви націлите на щось нижче, це не працює. Я пропоную використовувати відповідь jp36 нижче.
Патрік Буос

23

Альтернатива @pstoppani відповідь з підтримкою таблеток (Як @pstoppani відповідь, це буде працювати тільки на пристроях> 2,2)
-Tested на Samsung Galaxy SIIIіSamsung 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);
}

Спасибі, це працює відмінно , але я не розумію , що чому це перевірка з ||в rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90і з rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270. Тож у мене є 2 сумніви :::: по-перше, Чому ROTATION_0замість ROTATION_180другого випадку і ще чому чому перевіряти 0 ступінь 90, а не 180 ??
AndyBoy

@AndyBoy це стосується орієнтації пристроїв за замовчуванням. Зазвичай телефони мають орієнтацію портрета за замовчуванням, що означає, що обертання повертає нуль для портретного, але деякі планшети мають стандартний пейзаж, тобто обертання повертає нуль для пейзажу. Таким чином, різні ||перевірки обробляють дві можливі орієнтації за замовчуванням на основі ландшафту звітування пристрою проти портрета.
jp36

5

Ось мій код, ви можете заблокувати одним із цих методів ваш екран і як тільки закінчите завдання розблокувати його з 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);
    }

}

0

Ось переклад Xamarin відповіді @pstoppani вище.

ПРИМІТКА. Це для фрагмента, замініть активність. з цим. якщо використовується в межах діяльності.

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

Це не перевірено, як було застосовано з іншим підходом до його використання, але може бути корисним.


Це та сама відповідь, що і pstoppani, і на планшеті вона не вийде.
Тім Атін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.