2010-03-02 2 views
95

Есть ли способ заблокировать ориентацию во время выполнения? Например, я хотел бы разрешить пользователю блокировать экран в альбомной ориентации, если пользователь в настоящее время находится в ландшафтном режиме и переключает параметр меню.Как заблокировать ориентацию во время выполнения

ответ

119
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

Призыв к деятельности, будет запирать его на пейзаж. Ищите другие флаги в классе ActivityInfo. Вы можете заблокировать его до портрета или сделать его датчиком/слайдером.

Больше информации здесь: http://www.devx.com/wireless/Article/40792

+12

Хорошо спасибо. Это отлично работает. Это позволит получить текущую ориентацию. getResources(). GetConfiguration().ориентация – Jared

+6

Осторожно! Вам нужно различать то, что возвращает getConfiguration() и что хочет setRequestedOrientation - см. Мой ответ ниже для деталей –

+0

есть проблема с этим подходом. Убедитесь, что вы просмотрели комментарий [этого ответа] (http://stackoverflow.com/a/3614089/1708390) –

27

мне казалось, был иметь подобный случай. Я хотел поддержать любую ориентацию, но мне нужно было оставаться в текущей ориентации после определенного момента в рабочем процессе. Мое решение было:

При записи защищенного документооборота:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); 

При выходе из защищенного документооборота:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); 
+1

Это не относится к OQ, по крайней мере, на Android> = 16. setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) может настроить устройство на пейзаж, даже если он был в портрете, тогда как вопрос относится к фиксированной ориентации, которая была дана. – greg7gkb

+1

для меня, установка его в носенсер возвращает меня в портретный режим, если я был на пейзаже Вместо этого я использовал SCREEN_ORIENTATION_LOCKED, и это сработало для меня – Jimmar

+0

@JiMMaR SCREEN_ORIENTATION_LOCKED - лучший способ для Android> = 18. Но если вы нацелитесь на что-то ниже , это не работает. Я предлагаю использовать ответ jp36 ниже. –

95

Будьте осторожны разницы между тем, что 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); 
} 
+11

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

+0

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

45

Это работает на устройствах с обратным портретом и обратного ландшафта.

Блокировка ориентации:

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

Unlock ориентация:

getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); 
+4

Получить ротацию '" Возвращает поворот экрана из его «естественной» ориентации. »' [Источник] (http://developer.android.com/ ссылка/Android/просмотр/display.html # getRotation()). Так что на телефоне, говорящем, что ROTATION_0 - портрет, скорее всего, правильный, но на планшете его «естественная» ориентация, скорее всего, является ландшафтом, а ROTATION_0 должен возвращать пейзаж вместо портрета. – jp36

+0

@ jp36, я протестировал на Nexus 7, который имеет естественную ориентацию, которая совпадает с телефоном. Спасибо за тестирование на более крупном планшете (которого у меня нет). – pstoppani

+1

Как сказал jp36, он не работает на планшетах с естественной ориентацией ландшафта! – DominicM

19

Альтернатива @pstoppani ответ с поддержкой таблеток (Как @pstoppani ответ, это будет работает только на устройствах> 2.2)
-Попробовал на 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); 
} 
3

Вот мой код, можно зафиксировать с помощью одного из этих методов ваш экран и один раз закончил задачу разблокировать его с 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; 
} 

Это непроверено, поскольку вы использовали другой подход перед его использованием, но могут быть полезны.

+0

Это тот же ответ, что и pstoppani's, и он не сработает на планшете. –

Смежные вопросы