Làm cách nào để tắt thay đổi hướng trên Android?


287

Tôi có một ứng dụng mà tôi chỉ muốn sử dụng ở chế độ dọc, vì vậy tôi đã định nghĩa android: screenOrientation = "Portrait" trong tệp kê khai XML. Điều này hoạt động tốt cho điện thoại HTC Magic (và cũng ngăn chặn thay đổi hướng trên các điện thoại khác).

Nhưng tôi gặp vấn đề với điện thoại HTC G1 khi tôi mở bàn phím QWERTY phần cứng (không phải bàn phím ảo). Hoạt động của tôi vẫn ở chế độ dọc, nhưng dường như nó được khởi động lại và mất tất cả các trạng thái. Điều này không xảy ra với phiên bản HTC Hero .

Ứng dụng của tôi khá lớn, vì vậy tôi không muốn nó khởi động lại và mất tất cả các trạng thái khi bàn phím được mở. Làm thế nào tôi có thể ngăn chặn điều đó?


2
Hãy thử tìm kiếm ở đây: stackoverflow.com/questions/2366706/ Ấn
Andy Weinstein

Câu trả lời:


317

Cập nhật tháng 4 năm 2013: Đừng làm điều này. Đó không phải là một ý tưởng tốt trong năm 2009 khi tôi lần đầu tiên trả lời câu hỏi và bây giờ nó thực sự không phải là một ý tưởng tốt. Xem câu trả lời này của hackbod vì lý do:

Tránh tải lại hoạt động với asynctask khi thay đổi định hướng trong Android

Thêm android:configChanges="keyboardHidden|orientation"vào AndroidManifest.xml của bạn. Điều này cho hệ thống biết những thay đổi cấu hình mà bạn sẽ tự xử lý - trong trường hợp này bằng cách không làm gì cả.

<activity android:name="MainActivity"
     android:screenOrientation="portrait"
     android:configChanges="keyboardHidden|orientation">

Xem Cấu hình tham chiếu dành cho nhà phát triển để biết thêm chi tiết.

Tuy nhiên, ứng dụng của bạn có thể bị gián đoạn bất cứ lúc nào, ví dụ như bằng một cuộc gọi điện thoại, vì vậy bạn thực sự nên thêm mã để lưu trạng thái của ứng dụng khi bị tạm dừng.

Cập nhật: Kể từ Android 3.2, bạn cũng cần thêm "screenSize":

<activity
    android:name="MainActivity"
    android:screenOrientation="portrait"
    android:configChanges="keyboardHidden|orientation|screenSize">

Từ hướng dẫn dành cho nhà phát triển Xử lý thay đổi cấu hình

Thận trọng: Bắt đầu với Android 3.2 (API cấp 13), "kích thước màn hình" cũng thay đổi khi thiết bị chuyển giữa hướng dọc và hướng ngang. Do đó, nếu bạn muốn ngăn khởi động lại thời gian chạy do thay đổi hướng khi phát triển API cấp 13 trở lên (như được khai báo bởi các thuộc tính minSdkVersion và targetSdkVersion), bạn phải bao gồm giá trị "screenSize" bên cạnh giá trị "direction". Đó là, bạn phải khai báo android:configChanges="orientation|screenSize". Tuy nhiên, nếu ứng dụng của bạn nhắm mục tiêu API cấp 12 trở xuống, thì hoạt động của bạn luôn tự xử lý thay đổi cấu hình này (thay đổi cấu hình này không khởi động lại hoạt động của bạn, ngay cả khi chạy trên thiết bị Android 3.2 trở lên).


36
Chỉ cần thêm vào điều này và thực sự rõ ràng, Android có thể giết chết ứng dụng của bạn bất cứ lúc nào, bất kể thay đổi hướng, vì vậy bạn nên sử dụng onPause () và onSaveInstanceState () để lưu trạng thái, bất kể là gì.
Eric Mill

Bản cập nhật 3.2 rất hữu ích và là thứ đã chặn tôi. Tôi không biết tại sao trình xử lý onConfigurationChanged của tôi không bắn và đây là nó. Cảm ơn!
sweetlilmre

tham số thứ ba - screenSize không thể tìm thấy trong 2.3.x, tôi có nên đổi sang screenLayout không?
cá chết

2
@Lumma Không, "screenSize" chỉ cần cho Android 3.2 trở lên. API cấp độ nào bạn đang nhắm mục tiêu? Tôi nghĩ bạn chỉ cần thêm nó nếu bạn đang nhắm mục tiêu cấp 13 trở lên. Tôi sẽ cập nhật câu trả lời để làm rõ.
Mâu thuẫn

1
Chỉ trong trường hợp nó hữu ích cho người khác, tôi đã tìm thấy cả bạn <... android: configChanges = "direction" ...> để ghi đè các thay đổi và <... android: screenOrientation = "Portrait" ...> thành xác định mặc định.
Sogger

97

Bạn cần sửa đổi AndroidManifest.xml dưới dạng Intrications (trước đây là Ashton) và đảm bảo hoạt động xử lý sự kiện onConfigurationChanged như bạn muốn xử lý. Đây là cách nó sẽ trông:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

Theo ghi nhận của Dmitry Zaitsev, tốt hơn là đưa setRequestedOrientation()vào onCreate().
Timmmm

3
Không onConfigurationChanged()được gọi trước onCreate()nếu cài đặt hướng trước khi đặt nội dung Xem trong oncreate là cách tiếp cận tốt hơn , cài đặt cấu hình nơi nó thuộc về cũng sạch hơn nên câu trả lời này vẫn tốt.
Samuel

39

Tôi luôn thấy bạn cần cả hai

android:screenOrientation="nosensor" android:configChanges="keyboardHidden|orientation"

22

Như đã nói, hãy đặt android:configChangesHoạt động của bạn (trong tệp kê khai) thành keyboardHidden|orientationvà sau đó:

1) Ghi đè onConfigurationChanged()

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //here you can handle orientation change
}

2) Thêm dòng này vào hoạt động của bạn onCreate()

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Tốt hơn là thêm cùng một dòng onConfigurationChanged, vì ứng dụng của bạn sẽ chuyển sang chế độ dọc và sau đó trở lại ngang (nó sẽ chỉ xảy ra một lần, nhưng thật khó chịu).

Ngoài ra, bạn có thể thiết lập android:screenOrientation="nosensor"cho hoạt động của mình (trong bảng kê khai). Nhưng sử dụng theo cách này, bạn hoàn toàn không thể xử lý các thay đổi định hướng.


Tôi nên làm gì nếu tôi muốn tránh tạo lại hoạt động khi xoay vòng, nhưng tôi muốn cho phép người dùng khóa hướng thông qua cài đặt của HĐH?
nhà phát triển Android

@androiddeveloper là một câu hỏi riêng biệt, đã có câu trả lời: stackoverflow.com/a/14771495/926907
Dmitry Zaytsev

Liên kết của bạn là về việc tự thay đổi nội dung khi cấu hình thay đổi, nhưng tôi muốn tránh xoay vòng hoạt động (để nó giữ chính xác như vậy) trong trường hợp người dùng đã chọn khóa hướng qua hệ điều hành cài đặt (có sẵn trên một số thiết bị thông qua cài đặt nhanh, trong ngăn thông báo).
nhà phát triển Android

@androiddeveloper ah, tôi nghĩ tôi đã hiểu. Sau đó, hãy xem liên kết này: developer.android.com/reference/android/, Theo các tài liệu, định hướng mặc định sẽ đưa tài khoản của người dùng vào tài khoản. Nếu đó không phải là trường hợp, thì tôi nghi ngờ rằng đó là một hành vi cụ thể của hệ điều hành. Tôi sẽ rất vui khi nghe về kết quả của bạn - bây giờ tôi cũng quan tâm đến nó :)
Dmitry Zaytsev

Tôi biết mặc định sẽ xử lý các tùy chọn của người dùng, nhưng nó cũng tạo lại hoạt động khi bạn xoay màn hình, đây là điều tôi không muốn có.
nhà phát triển Android


13

Trong phương pháp OnCreate của hoạt động của bạn sử dụng mã này:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

Bây giờ định hướng của bạn sẽ được đặt thành chân dung và sẽ không bao giờ thay đổi.


4
Với điều đó, bạn không ngăn khởi động lại hoạt động mỗi khi cấu hình định hướng thay đổi.
AxeEffect

Ngoài ra, điều này không hoạt động nếu bạn nhập Hoạt động từ Hoạt động trước theo hướng ngang.
w3bshark

10

Trong tệp AndroidManifest.xml, đối với mỗi hoạt động bạn muốn khóa, hãy thêm screenOrientationdòng cuối cùng :

android:label="@string/app_name"
android:name=".Login"
android:screenOrientation="portrait" >

Hoặc android: screenOrientation = "phong cảnh" .


8

Trong tệp androidmanifest.xml của bạn :

   <activity android:name="MainActivity" android:configChanges="keyboardHidden|orientation">

hoặc là

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

6

Để khóa màn hình theo mã, bạn phải sử dụng vòng xoay thực tế của màn hình (0, 90, 180, 270) và bạn phải biết vị trí tự nhiên của nó, trong điện thoại thông minh, vị trí tự nhiên sẽ là chân dung và trong máy tính bảng, nó sẽ là phong cảnh

Đây là mã (phương pháp khóa và mở khóa), nó đã được thử nghiệm trên một số thiết bị (điện thoại thông minh và máy tính bảng) và nó hoạt động rất tốt.

public static void lockScreenOrientation(Activity activity)
{   
    WindowManager windowManager =  (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);   
    Configuration configuration = activity.getResources().getConfiguration();   
    int rotation = windowManager.getDefaultDisplay().getRotation(); 

    // Search for the natural position of the device    
    if(configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&  
       (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) ||  
       configuration.orientation == Configuration.ORIENTATION_PORTRAIT &&   
       (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270))   
    {   
        // Natural position is Landscape    
        switch (rotation)   
        {   
            case Surface.ROTATION_0:    
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);    
                break;      
            case Surface.ROTATION_90:   
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
            break;      
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
                break;
        }
    }
    else
    {
        // Natural position is Portrait
        switch (rotation) 
        {
            case Surface.ROTATION_0: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
            break;   
            case Surface.ROTATION_90: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
            break;   
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;
        }
    }
}

public static void unlockScreenOrientation(Activity activity)
{
    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}

những gì paramater nên được thông qua như là hoạt động?
CHÚC MỪNG

Hoạt động gọi phương thức để khóa / mở khóa hướng của nó. Đó là một phương thức tiện ích tĩnh công cộng được gọi từ các hoạt động khác nhau.
PoOk

1
Hoạt động tuyệt vời, nhưng, nghiêm túc, Android, tại sao chúng ta phải làm tất cả những điều đó chỉ để định hướng màn hình khóa? !!!
Cocorico

Đúng. Điều này khóa định hướng như chúng ta làm trong bảng kê khai. Điều này sẽ ngăn onConfigurationChanged không được gọi nữa. Có một phương pháp khóa UI thành Cảnh và vẫn gọi onConfigurationChanged. Giống như ứng dụng máy ảnh trong Android
Ajith Memana

Có một cờ SCREEN_ORIENTATION_LOCKED trên SDK 18+ dường như hoạt động nhưng bạn vẫn muốn sử dụng mã ở trên để hỗ trợ mọi thiết bị
DominicM

2

Trong Visual Studio Xamarin:

  1. Thêm vào:

using Android.Content.PM; để bạn danh sách không gian tên hoạt động.

  1. Thêm vào:

[Activity(ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)]

như một thuộc tính cho lớp bạn, như thế:

[Activity(ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : Activity
{...}

Câu hỏi này là hỏi về Android, không phải Xamarin.Android
Trevor Hart

1

Thêm vào

android:configChanges="keyboardHidden|orientation|screenSize" 

để bảng kê khai của bạn.


bên trong thẻ <Activity> của bạn
Ege Kuzubasioglu

0

Xin lưu ý, không có phương pháp nào có vẻ hoạt động ngay bây giờ!

Trong Android Studio 1 một cách đơn giản là thêm android:screenOrientation="nosensor".

Điều này có hiệu quả khóa hướng màn hình.

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.