如何在运行时锁定方向


107

有没有一种方法可以在运行时锁定方向?例如,如果用户当前处于横向,我希望允许用户将屏幕锁定为横向,并切换菜单选项。

Answers:


133
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

调用了一项活动,将其锁定为横向。在ActivityInfo类中查找其他标志。您可以将其锁定为纵向或使其由传感器/滑块驱动。

此处了解更多信息:http : //www.devx.com/wireless/Article/40792


13
好,谢谢。这很好。那将得到当前的方向。getResources()。getConfiguration()。orientation
Jared 2010年

7
小心!您需要区分getConfiguration()返回的内容和setRequestedOrientation想要的内容-有关详细信息,请参见下面的答案
Andy Weinstein

这种方法存在问题。确保您已通过此答案
Bug发生

但它为所有的活动相同的方向,是否有任何其它的方式,我们可以改变方向
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更好,因为SCREEN_ORIENTATION_SENSOR允许自由旋转,即使设置不允许。
史蒂夫·沃林

辉煌!需要补充的是,当您切换到反向时,不会进行重新配置。至少在我测试过的设备上。知道是否要在某些对话框显示等期间停止重新配置非常重要
sberezin 2015年

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应该返回横向而不是纵向。
2013年

@ jp36,我在具有与手机相同的自然方向的Nexus 7上进行了测试。感谢您在更大的平板电脑上测试(我没有)。
pstoppani

1
如jp36所述,它不适用于自然风景取向的平板电脑!
DominicM

我们如何在设备中测试反向肖像?
AndyBoy

27

我似乎也有类似的情况。我想支持任何方向,但是在工作流中的某个点之后,我需要保持当前方向。我的解决方案是:

在进入受保护的工作流程时:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

在受保护工作流程的出口:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

2
至少在Android> = 16上,这不能解决OQ问题。setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR)可能会将设备设置为横向(即使它是纵向的),而问题是给出的锁定方向。
greg7gkb

3
对我来说,将其设置为nosensor会使我回到人像模式(如果我在风景上),我改用SCREEN_ORIENTATION_LOCKED,它对我
有用

1
@JiMMaR SCREEN_ORIENTATION_LOCKED是适用于Android> = 18的最佳方法。但是,如果您定位的目标较低,则该方法将无效。我建议在下面使用jp36的答案。
Patrick Boos

23

支持平板电脑的@pstoppani答案的替代方法(与@pstoppani答案一样,这仅适用于> 2.2的设备)
-在Samsung Galaxy SIIISamsung 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);
}

谢谢,它工作正常,但我不明白为什么要使用||in rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90和with进行检查rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270。所以我有2个疑问:::::首先,为什么要ROTATION_0代替ROTATION_180第二种情况,另一个为什么要用90而不是180检查0度?
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

这是@pstoppani的答案的Xamarin转换。

注意:这是为一个片段,替换活动。此。如果在活动中使用。

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的答案相同,并且在平板电脑上将失败。
Tim Autin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.