Bagaimana cara menonaktifkan perubahan orientasi di Android?


287

Saya memiliki aplikasi yang ingin saya gunakan dalam mode potret, jadi saya telah mendefinisikan android: screenOrientation = "portrait" di manifes XML. Ini berfungsi baik untuk ponsel HTC Magic (dan juga mencegah perubahan orientasi pada ponsel lain).

Tapi saya punya masalah dengan ponsel HTC G1 saat saya membuka perangkat keras keyboard QWERTY (bukan keyboard virtual). Aktivitas saya tetap dalam mode potret, tetapi sepertinya memulai kembali dan kehilangan semua statusnya. Ini tidak terjadi dengan HTC Hero .

Aplikasi saya cukup besar, jadi saya tidak ingin restart dan kehilangan semua statusnya saat keyboard dibuka. Bagaimana saya bisa mencegahnya?



Jawaban:


317

Pembaruan April 2013: Jangan lakukan ini. Itu bukan ide yang baik pada tahun 2009 ketika saya pertama kali menjawab pertanyaan dan itu sebenarnya bukan ide yang baik sekarang. Lihat jawaban ini oleh hackbod untuk alasan:

Hindari memuat ulang aktivitas dengan asynctask pada perubahan orientasi di android

Tambahkan android:configChanges="keyboardHidden|orientation"ke AndroidManifest.xml Anda. Ini memberi tahu sistem perubahan konfigurasi apa yang akan Anda tangani sendiri - dalam hal ini dengan tidak melakukan apa pun.

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

Lihat Konfigurasi referensi pengembang untuk lebih jelasnya.

Namun, aplikasi Anda dapat diinterupsi kapan saja, misalnya dengan panggilan telepon, jadi Anda harus menambahkan kode untuk menyimpan status aplikasi Anda ketika dijeda.

Pembaruan: Pada Android 3.2, Anda juga perlu menambahkan "screenSize":

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

Dari panduan Pengembang Menangani Konfigurasi Ubah Diri Anda

Perhatian: Dimulai dengan Android 3.2 (API level 13), "ukuran layar" juga berubah ketika perangkat beralih antara orientasi potret dan lanskap. Dengan demikian, jika Anda ingin mencegah restart runtime karena perubahan orientasi ketika mengembangkan untuk API level 13 atau lebih tinggi (sebagaimana dideklarasikan oleh atribut minSdkVersion dan targetSdkVersion), Anda harus menyertakan nilai "screenSize" di samping nilai "orientasi". Artinya, Anda harus menyatakan android:configChanges="orientation|screenSize". Namun, jika aplikasi Anda menargetkan API level 12 atau lebih rendah, maka aktivitas Anda selalu menangani perubahan konfigurasi itu sendiri (perubahan konfigurasi ini tidak memulai kembali aktivitas Anda, bahkan ketika berjalan pada perangkat Android 3.2 atau lebih tinggi).


36
Hanya untuk menambahkan ini dan menjadi sangat eksplisit, Android tanpa ampun dapat membunuh aplikasi Anda kapan saja, terlepas dari perubahan orientasi, jadi Anda harus menggunakan onPause () dan onSaveInstanceState () untuk menyimpan keadaan, apa pun yang terjadi.
Eric Mill

Pembaruan 3.2 sangat berguna dan menghalangi saya. Saya tidak tahu mengapa handler onConfigurationChanged saya tidak menyala dan ini dia. Terima kasih!
sweetlilmre

param ketiga - screenSize tidak dapat ditemukan di 2.3.x, haruskah saya mengubah ke screenLayout?
deadfish

2
@Lumma Tidak, "screenSize" hanya diperlukan untuk Android 3.2 dan yang lebih baru. API tingkat apa yang Anda targetkan? Saya pikir Anda hanya perlu menambahkannya jika Anda menargetkan level 13 atau lebih tinggi. Saya akan memperbarui jawaban untuk menjelaskan.
Intrications

1
Untuk berjaga-jaga jika hal ini bermanfaat bagi orang lain, saya telah menemukan Anda berdua <... android: configChanges = "orientasi" ...> untuk mengabaikan perubahan dan <... android: screenOrientation = "portrait" ...> to tentukan default.
Sogger

97

Anda perlu memodifikasi AndroidManifest.xml sebagai Intrications (sebelumnya Ashton) yang disebutkan dan memastikan aktivitas menangani acara onConfigurationChanged seperti yang Anda inginkan ditangani. Begini tampilannya:

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

Sebagaimana dicatat oleh Dmitry Zaitsev, lebih baik untuk menempatkan setRequestedOrientation()di onCreate().
Timmmm

3
Tidak onConfigurationChanged()dipanggil sebelumnya onCreate()jika begitu mengatur orientasi sebelum mengatur kontenDilihat di oncreate adalah pendekatan yang lebih baik , pengaturan konfigurasi di tempat itu juga lebih bersih sehingga jawaban ini masih bagus.
Samuel

39

Saya selalu menemukan Anda membutuhkan keduanya

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

22

Seperti yang dikatakan, set android:configChangesAktivitas Anda (dalam file manifes) kekeyboardHidden|orientation dan kemudian:

1) Override onConfigurationChanged()

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

2) Tambahkan baris ini ke aktivitas Anda onCreate()

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Lebih baik daripada menambahkan baris yang sama onConfigurationChanged , karena aplikasi Anda akan beralih ke mode potret dan kemudian kembali ke lansekap (itu akan terjadi hanya satu kali, tetapi itu menjengkelkan).

Anda juga dapat mengatur android:screenOrientation="nosensor"aktivitas Anda (dalam manifes). Tetapi dengan menggunakan cara ini Anda tidak dapat menangani perubahan orientasi sama sekali.


Apa yang harus saya lakukan jika saya ingin menghindari penciptaan kembali aktivitas setelah rotasi, namun saya ingin memungkinkan pengguna untuk mengunci orientasi melalui pengaturan OS?
pengembang android

@androiddeveloper bahwa pertanyaan terpisah, yang sudah memiliki jawaban: stackoverflow.com/a/14771495/926907
Dmitry Zaytsev

Tautan Anda adalah tentang mengubah konten sendiri ketika konfigurasi berubah, namun saya ingin menghindari rotasi aktivitas (sehingga terlihat seperti apa adanya) jika pengguna telah memilih untuk mengunci orientasi melalui OS. pengaturan (tersedia di beberapa perangkat melalui pengaturan cepat, di laci pemberitahuan).
pengembang android

@androiddeveloper ah, saya pikir saya mengerti. Kemudian lihat tautan ini: developer.android.com/reference/android/... Menurut dokumen, orientasi default harus sudah mempertimbangkan preferensi pengguna. Jika bukan itu masalahnya, maka saya curiga itu adalah perilaku spesifik OS. Saya akan senang mendengar tentang hasil Anda - sekarang saya juga tertarik di dalamnya :)
Dmitry Zaytsev

Saya tahu default akan menangani preferensi pengguna, tetapi itu juga menciptakan kembali aktivitas ketika Anda memutar layar, yang merupakan sesuatu yang saya tidak ingin miliki.
pengembang android


13

Dalam metode OnCreate aktivitas Anda, gunakan kode ini:

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

Sekarang orientasi Anda akan diatur ke potret dan tidak akan pernah berubah.


4
Dengan itu Anda tidak mencegah memulai kembali aktivitas setiap kali konfigurasi orientasi berubah.
AxeEffect

Juga, ini tidak berfungsi jika Anda memasukkan Aktivitas dari Aktivitas sebelumnya dalam orientasi lanskap.
w3bshark

10

Di file AndroidManifest.xml, untuk setiap aktivitas yang ingin Anda kunci tambahkan screenOrientationbaris terakhir :

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

Atau android: screenOrientation = "landscape" .


8

Dalam file androidmanifest.xml Anda :

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

atau

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

6

Untuk mengunci layar dengan kode Anda harus menggunakan rotasi layar yang sebenarnya (0, 90, 180, 270) dan Anda harus tahu posisi alami layar itu, di smartphone posisi alami akan menjadi potret dan di tablet, itu akan menjadi lanskap.

Inilah kodenya (metode kunci dan buka kunci), ini telah diuji di beberapa perangkat (ponsel cerdas dan tablet) dan berfungsi dengan baik.

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

paramater apa yang harus dilewatkan sebagai aktivitas?
WISHY

Aktivitas yang memanggil metode untuk mengunci / membuka orientasinya. Itu metode utilitas statis publik untuk dipanggil dari Kegiatan differents.
PoOk

1
Berfungsi bagus, tapi, serius, Android, mengapa kita harus melakukan semua itu hanya untuk orientasi layar kunci? !!!
Cocorico

Iya. Yang ini mengunci orientasi seperti yang kita lakukan dalam manifes. Ini akan mencegah onConfigurationChanged dari dipanggil lagi. Apakah ada metode yang mengunci UI ke Landscape dan masih memanggil onConfigurationChanged. Sama seperti aplikasi kamera di android tidak
Ajith Memana

Ada bendera SCREEN_ORIENTATION_LOCKED di SDK 18+ yang tampaknya berfungsi tetapi Anda masih ingin menggunakan kode di atas untuk mendukung setiap perangkat
DominicM

2

Dalam Visual Studio Xamarin:

  1. Menambahkan:

using Android.Content.PM; untuk Anda daftar namespace aktivitas.

  1. Menambahkan:

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

sebagai atribut untuk kelas Anda, seperti itu:

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

Pertanyaan ini menanyakan tentang Android, bukan Xamarin. Android
Trevor Hart


0

Harap dicatat, tidak ada satupun metode yang tampaknya berfungsi sekarang!

Di Android Studio 1, satu cara sederhana adalah menambahkan android:screenOrientation="nosensor".

Ini secara efektif mengunci orientasi layar.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.