Cách khóa hướng trong thời gian chạy


107

Có cách nào để khóa định hướng trong thời gian chạy không? Ví dụ: tôi muốn cho phép người dùng khóa màn hình theo chiều ngang nếu người dùng hiện đang ở chế độ ngang và chuyển đổi tùy chọn menu.

Câu trả lời:


133
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Được gọi trên một hoạt động, sẽ khóa nó ở chế độ ngang. Tìm các cờ khác trong lớp ActivityInfo. Bạn có thể khóa nó về chế độ dọc hoặc làm cho nó điều khiển bằng cảm biến / thanh trượt.

Thông tin thêm tại đây: http://www.devx.com/wireless/Article/40792


13
Được rồi cảm ơn. Điều này hoạt động tuyệt vời. Điều đó sẽ có được định hướng hiện tại. getResources (). getConfiguration (). hướng
Jared

7
Cẩn thận! Bạn cần phân biệt giữa những gì getConfiguration () trả về và những gì setRequestedOrientation muốn - hãy xem câu trả lời của tôi bên dưới để biết chi tiết
Andy Weinstein

có một vấn đề với cách tiếp cận này. Hãy chắc chắn rằng bạn xem qua phần bình luận của câu trả lời này
Lỗi xảy ra vào

nhưng nó đặt cùng một hướng cho tất cả các hoạt động, có cách nào khác mà chúng ta có thể thay đổi hướng
silverFoxA

106

Hãy cẩn thận về sự khác biệt giữa những gì getConfiguration trả về và những gì setRequestedOrientation muốn - cả hai đều là int, nhưng chúng đến từ các định nghĩa hằng số khác nhau.

Đây là cách khóa hướng hiện tại, đồng thời cho phép lật 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
Bạn có thể thích sử dụng SCREEN_ORIENTATION_USER_LANDSCAPE vì điều này không cho phép lật 180 độ nếu người dùng đã tắt xoay màn hình trong cài đặt. Tương tự như vậy khi chuyển trở lại chế độ xoay tự do, SCREEN_ORIENTATION_USER tốt hơn SCREEN_ORIENTATION_SENSOR vì sau này cho phép xoay tự do ngay cả khi cài đặt cho phép không.
Steve Waring

Xuất sắc! Cần thêm rằng khi bạn chuyển sang cấu hình lại hướng ngược lại không xảy ra. Ít nhất là trên các thiết bị tôi đã thử nghiệm. Đó là thực sự quan trọng để biết nếu bạn muốn dừng lại cấu hình lại trong một số chương trình thoại vv
sberezin

47

Tính năng này hoạt động trên các thiết bị có chế độ dọc và ngang ngược.

Định hướng khóa:

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

Mở khóa định hướng:

   getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

5
Nhận "Returns the rotation of the screen from its "natural" orientation." nguồn xoay vòng . Vì vậy, trên điện thoại nói ROTATION_0 là dọc có thể đúng, nhưng trên máy tính bảng, hướng "tự nhiên" của nó có thể là hướng ngang và ROTATION_0 sẽ trả về hướng ngang thay vì dọc.
jp36

@ jp36, tôi đã thử nghiệm trên Nexus 7 có hướng tự nhiên giống với điện thoại. Cảm ơn bạn đã thử nghiệm trên một máy tính bảng lớn hơn (mà tôi không có).
pstoppani

1
Như jp36 đã nói, nó không hoạt động trên máy tính bảng có hướng phong cảnh tự nhiên!
DominicM

Làm thế nào để chúng tôi kiểm tra dọc ngược trong thiết bị ??
AndyBoy

27

Tôi dường như đã có một trường hợp tương tự. Tôi muốn hỗ trợ bất kỳ định hướng nào, nhưng tôi cần duy trì định hướng hiện tại sau một thời điểm nhất định trong quy trình làm việc. Giải pháp của tôi là:

Khi nhập dòng công việc được bảo vệ:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

Khi thoát khỏi quy trình làm việc được bảo vệ:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

2
Điều này không giải quyết được OQ, ít nhất là trên Android> = 16. setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) có thể đặt thiết bị ở chế độ ngang ngay cả khi nó ở chế độ dọc, trong khi câu hỏi đề cập đến hướng khóa đã được đưa ra.
greg7gkb

3
với tôi, đặt nó vào nosensor đưa tôi trở lại chế độ chân dung nếu tôi là về cảnh quan tôi sử dụng SCREEN_ORIENTATION_LOCKED thay vào đó và nó làm việc cho tôi
Jimmar

1
@JiMMaR SCREEN_ORIENTATION_LOCKED là cách tốt nhất cho Android> = 18. Nhưng trong trường hợp bạn nhắm mục tiêu thứ gì đó thấp hơn, điều đó không hoạt động. Tôi đề nghị sử dụng câu trả lời của jp36 bên dưới.
Patrick Boos

23

Thay thế cho câu trả lời @pstoppani với sự hỗ trợ cho máy tính bảng (Cũng như câu trả lời @pstoppani, điều này sẽ chỉ hoạt động trên các thiết bị> 2.2) -
Đã kiểm tra trên 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);
}

Cảm ơn, Nó làm việc tốt nhưng tôi không hiểu rằng tại sao nó là kiểm tra với ||trong rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90và với rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270. Vì vậy, tôi có 2 nghi ngờ :::: đầu tiên, Tại sao ROTATION_0thay vì ROTATION_180trong trường hợp thứ hai và khác tại sao kiểm tra 0 độ với 90 không phải 180 ??
AndyBoy

@AndyBoy nó phải làm với hướng mặc định của thiết bị. Thông thường, điện thoại có hướng mặc định là dọc, nghĩa là xoay trả về 0 cho dọc, nhưng một số máy tính bảng có mặc định là ngang có nghĩa là xoay trả về 0 cho ngang. Vì vậy, các ||kiểm tra khác nhau đang xử lý hai hướng mặc định có thể có dựa trên phong cảnh báo cáo thiết bị so với dọc.
jp36

5

Đây là mã của tôi, bạn có thể khóa màn hình của mình bằng một trong các phương pháp này và sau khi hoàn thành nhiệm vụ, hãy mở khóa bằng 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

Đây là chuyển đổi Xamarin của câu trả lời của @pstoppani ở trên.

LƯU Ý: đây là cho một Fragment, thay thế Activity. với cái này. nếu được sử dụng trong một hoạt động.

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

Điều này chưa được kiểm tra như đã xảy ra với một cách tiếp cận khác trước khi sử dụng nó, nhưng có thể được sử dụng.


Đây là câu trả lời giống như câu trả lời của pstoppani, và nó sẽ không thành công trên máy tính bảng.
Tim Autin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.